1 /*
2 * Copyright (c) 2009-2018, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file        mos_utilities_specific.c
24 //! \brief        This module implements the MOS wrapper functions for Linux/Android
25 //!
26 
27 #include "mos_utilities_specific.h"
28 #include "mos_utilities.h"
29 #include "mos_util_debug.h"
30 #include <fcntl.h>     // open
31 #include <stdlib.h>    // atoi
32 #include <string.h>    // strlen, strcat, etc.
33 #include <errno.h>     // strerror(errno)
34 #include <time.h>      // get_clocktime
35 #include <sys/stat.h>  // fstat
36 #include <dlfcn.h>     // dlopen, dlsym, dlclose
37 #include <sys/types.h>
38 #include <unistd.h>
39 #if _MEDIA_RESERVED
40 #include "codechal_user_settings_mgr_ext.h"
41 #include "vphal_user_settings_mgr_ext.h"
42 #endif // _MEDIA_RESERVED
43 #ifndef ANDROID
44 #include <sys/ipc.h>   // System V IPC
45 #include <sys/types.h>
46 #include <sys/sem.h>
47 #include <signal.h>
48 #include <unistd.h>    // fork
49 #else
50 #include <cutils/properties.h>
51 #endif // ANDROID
52 
53 #include "mos_utilities_specific_next.h"
54 static const char* szUserFeatureFile = USER_FEATURE_FILE;
55 
56 #if _MEDIA_RESERVED
57 static MediaUserSettingsMgr *codecUserFeatureExt = nullptr;
58 static MediaUserSettingsMgr *vpUserFeatureExt    = nullptr;
59 #endif
60 
61 
62 #ifdef __cplusplus
63 
startTick(std::string tag)64 void PerfUtility::startTick(std::string tag)
65 {
66     Tick newTick = {};
67     struct timespec ts = {};
68 
69     // get start tick count
70     clock_gettime(CLOCK_REALTIME, &ts);
71     newTick.start = int(ts.tv_sec * 1000000) + int(ts.tv_nsec / 1000); // us
72 
73     std::vector<Tick> *perf = nullptr;
74     std::map<std::string, std::vector<Tick>*>::iterator it;
75     it = records.find(tag);
76     if (it == records.end())
77     {
78         perf = new std::vector<Tick>;
79         perf->push_back(newTick);
80         records[tag] = perf;
81     }
82     else
83     {
84         it->second->push_back(newTick);
85     }
86 }
87 
stopTick(std::string tag)88 void PerfUtility::stopTick(std::string tag)
89 {
90     struct timespec ts = {};
91     std::map<std::string, std::vector<Tick>*>::iterator it;
92     it = records.find(tag);
93     if (it == records.end())
94     {
95         // should not happen
96         return;
97     }
98 
99     // get stop tick count
100     clock_gettime(CLOCK_REALTIME, &ts);
101     it->second->back().stop = int(ts.tv_sec * 1000000) + int(ts.tv_nsec / 1000); // us
102 
103     // calculate time interval
104     it->second->back().time = double(it->second->back().stop - it->second->back().start) / 1000.0; // ms
105 }
106 
107 #endif // __cplusplus
108 
109 //!
110 //! \brief    Get current run time
111 //! \details  Get current run time in us
112 //! \return   double
113 //!           Returns time in us
114 //!
MOS_GetTime()115 double MOS_GetTime()
116 {
117     struct timespec ts = {};
118     clock_gettime(CLOCK_REALTIME, &ts);
119     return double(ts.tv_sec) * 1000000.0 + double(ts.tv_nsec) / 1000.0;
120 }
121 
122 //!
123 //! \brief Linux specific user feature define, used in MOS_UserFeature_ParsePath
124 //!        They can be unified with the win definitions, since they are identical.
125 //!
126 #define MOS_UF_SEPARATOR  "\\"
127 #define MOS_UFKEY_EXT     "UFKEY_EXTERNAL"
128 #define MOS_UFKEY_INT     "UFKEY_INTERNAL"
129 PUFKEYOPS      pUFKeyOps = nullptr;
130 
131 extern int32_t MosMemAllocCounterNoUserFeature;
132 extern int32_t MosMemAllocCounterNoUserFeatureGfx;
133 
134 //!
135 //! \brief Linux specific trace entry path and file description.
136 //!
137 const char * const MosTracePath = "/sys/kernel/debug/tracing/trace_marker";
138 static int32_t MosTraceFd = -1;
139 
140 //!
141 //! \brief for int64_t/uint64_t format print warning
142 //!
143 #if __WORDSIZE == 64
144 #define __MOS64_PREFIX    "l"
145 #else
146 #define __MOS64_PREFIX    "ll"
147 #endif
148 
149 #define MOSd64     __MOS64_PREFIX "d"
150 #define MOSu64     __MOS64_PREFIX "u"
151 
152 //!
153 //! \brief mutex for mos utilities multi-threading protection
154 //!
155 MOS_MUTEX gMosUtilMutex = PTHREAD_MUTEX_INITIALIZER;
156 
157 static uint32_t uiMOSUtilInitCount = 0; // number count of mos utilities init
158 
MOS_SecureStrcat(char * strDestination,size_t numberOfElements,const char * const strSource)159 MOS_STATUS MOS_SecureStrcat(char  *strDestination, size_t numberOfElements, const char * const strSource)
160 {
161     if ( (strDestination == nullptr) || (strSource == nullptr) )
162     {
163         return MOS_STATUS_INVALID_PARAMETER;
164     }
165 
166     if(strnlen(strDestination, numberOfElements) == numberOfElements) // Not null terminated
167     {
168         return MOS_STATUS_INVALID_PARAMETER;
169     }
170 
171     if((strlen(strDestination) + strlen(strSource)) >= numberOfElements) // checks space for null termination.
172     {
173         return MOS_STATUS_INVALID_PARAMETER;
174     }
175 
176     strcat(strDestination, strSource);
177     return MOS_STATUS_SUCCESS;
178 }
179 
MOS_SecureStrtok(char * strToken,const char * strDelimit,char ** contex)180 char  *MOS_SecureStrtok(
181     char                *strToken,
182     const char          *strDelimit,
183     char                **contex)
184 {
185     return strtok_r(strToken, strDelimit, contex);
186 }
187 
MOS_SecureStrcpy(char * strDestination,size_t numberOfElements,const char * const strSource)188 MOS_STATUS MOS_SecureStrcpy(char  *strDestination, size_t numberOfElements, const char * const strSource)
189 {
190     if ( (strDestination == nullptr) || (strSource == nullptr) )
191     {
192         return MOS_STATUS_INVALID_PARAMETER;
193     }
194 
195     if ( numberOfElements <= strlen(strSource) ) // checks if there is space for null termination after copy.
196     {
197         return MOS_STATUS_INVALID_PARAMETER;
198     }
199 
200     strcpy(strDestination, strSource);
201 
202     return MOS_STATUS_SUCCESS;
203 }
204 
MOS_SecureMemcpy(void * pDestination,size_t dstLength,PCVOID pSource,size_t srcLength)205 MOS_STATUS MOS_SecureMemcpy(void  *pDestination, size_t dstLength, PCVOID pSource, size_t srcLength)
206 {
207     if ( (pDestination == nullptr) || (pSource == nullptr) )
208     {
209         return MOS_STATUS_INVALID_PARAMETER;
210     }
211 
212     if ( dstLength < srcLength )
213     {
214         return MOS_STATUS_INVALID_PARAMETER;
215     }
216     if(pDestination != pSource)
217     {
218         memcpy(pDestination, pSource, srcLength);
219     }
220 
221     return MOS_STATUS_SUCCESS;
222 }
223 
MOS_SecureFileOpen(FILE ** ppFile,const char * filename,const char * mode)224 MOS_STATUS MOS_SecureFileOpen(
225     FILE       **ppFile,
226     const char *filename,
227     const char *mode)
228 {
229     PFILE fp;
230 
231     if ((ppFile == nullptr) || (filename == nullptr) || (mode == nullptr))
232     {
233         return MOS_STATUS_INVALID_PARAMETER;
234     }
235 
236     fp = fopen(filename, mode);
237 
238     if (fp == nullptr)
239     {
240         *ppFile = nullptr;
241         return MOS_STATUS_FILE_OPEN_FAILED;
242     }
243     else
244     {
245         *ppFile = fp;
246         return MOS_STATUS_SUCCESS;
247     }
248 }
249 
MOS_SecureStringPrint(char * buffer,size_t bufSize,size_t length,const char * const format,...)250 int32_t MOS_SecureStringPrint(char  *buffer, size_t bufSize, size_t length, const char * const format, ...)
251 {
252     int32_t iRet = -1;
253     va_list var_args;
254 
255     if((buffer == nullptr) || (format == nullptr) || (bufSize < length))
256     {
257         return iRet;
258     }
259 
260     va_start(var_args, format);
261 
262     iRet = vsnprintf(buffer, length, format, var_args);
263 
264     va_end(var_args);
265 
266     return iRet;
267 }
268 
MOS_SecureVStringPrint(char * buffer,size_t bufSize,size_t length,const char * const format,va_list var_args)269 MOS_STATUS MOS_SecureVStringPrint(char  *buffer, size_t bufSize, size_t length, const char * const format, va_list var_args)
270 {
271     if((buffer == nullptr) || (format == nullptr) || (bufSize < length))
272     {
273         return MOS_STATUS_INVALID_PARAMETER;
274     }
275 
276     vsnprintf(buffer, length, format, var_args);
277 
278     return MOS_STATUS_SUCCESS;
279 }
280 
MOS_GetFileSize(HANDLE hFile,uint32_t * lpFileSizeLow,uint32_t * lpFileSizeHigh)281 MOS_STATUS MOS_GetFileSize(
282     HANDLE              hFile,
283     uint32_t            *lpFileSizeLow,
284     uint32_t            *lpFileSizeHigh)
285 {
286     struct stat     Buf;
287     MOS_UNUSED(lpFileSizeHigh);
288 
289     if((hFile == nullptr) || (lpFileSizeLow == nullptr))
290     {
291         return MOS_STATUS_INVALID_PARAMETER;
292     }
293 
294     if ( (fstat((intptr_t)hFile, &Buf)) < 0 )
295     {
296         *lpFileSizeLow = 0;
297         return MOS_STATUS_INVALID_FILE_SIZE;
298     }
299     *lpFileSizeLow  = (uint32_t)Buf.st_size;
300 
301     //to-do, lpFileSizeHigh store high 32-bit of File size
302     return MOS_STATUS_SUCCESS;
303 }
304 
MOS_CreateDirectory(char * const lpPathName)305 MOS_STATUS MOS_CreateDirectory(
306     char * const       lpPathName)
307 {
308     uint32_t   mode;
309     MOS_STATUS eStatus = MOS_STATUS_UNKNOWN;
310 
311     MOS_OS_CHK_NULL(lpPathName);
312 
313     // Set read/write access right for usr/group.
314     mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP;
315     if (mkdir(lpPathName, mode) < 0 &&
316         errno != EEXIST) // Directory already exists, don't return failure in this case.
317     {
318         MOS_OS_ASSERTMESSAGE("Failed to create the directory '%s'. Error = %s", lpPathName, strerror(errno));
319         eStatus = MOS_STATUS_DIR_CREATE_FAILED;
320         goto finish;
321     }
322 
323     eStatus = MOS_STATUS_SUCCESS;
324 
325 finish:
326     return eStatus;
327 }
328 
MOS_CreateFile(PHANDLE pHandle,char * const lpFileName,uint32_t iOpenFlag)329 MOS_STATUS MOS_CreateFile(
330     PHANDLE             pHandle,
331     char * const        lpFileName,
332     uint32_t            iOpenFlag)
333 {
334     int32_t             iFileDescriptor;
335     uint32_t            mode;
336 
337     if((lpFileName == nullptr) || (pHandle == nullptr))
338     {
339         return MOS_STATUS_INVALID_PARAMETER;
340     }
341     //set read/write access right for usr/group, mMode only takes effect when
342     //O_CREAT is set
343     mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
344     if ( (iFileDescriptor = open(lpFileName, iOpenFlag, mode)) < 0 )
345     {
346         *pHandle = (HANDLE)((intptr_t) iFileDescriptor);
347         return MOS_STATUS_INVALID_HANDLE;
348     }
349 
350     *pHandle = (HANDLE)((intptr_t) iFileDescriptor);
351     return MOS_STATUS_SUCCESS;
352 }
353 
MOS_ReadFile(HANDLE hFile,void * lpBuffer,uint32_t bytesToRead,uint32_t * pBytesRead,void * lpOverlapped)354 MOS_STATUS MOS_ReadFile(
355     HANDLE  hFile,
356     void    *lpBuffer,
357     uint32_t bytesToRead,
358     uint32_t *pBytesRead,
359     void    *lpOverlapped)
360 {
361     size_t  nNumBytesToRead;
362     ssize_t nNumBytesRead;
363     MOS_UNUSED(lpOverlapped);
364 
365     if((hFile == nullptr) || (lpBuffer == nullptr) || (pBytesRead == nullptr))
366     {
367         return MOS_STATUS_INVALID_PARAMETER;
368     }
369 
370     nNumBytesToRead   = (size_t)bytesToRead;
371     nNumBytesRead     = 0;
372 
373     //To-do: process lpOverlapped
374 
375     if ((nNumBytesRead = read((intptr_t)hFile, lpBuffer, nNumBytesToRead)) < 0)
376     {
377         *pBytesRead = 0;
378         return MOS_STATUS_FILE_READ_FAILED;
379     }
380 
381     *pBytesRead = (uint32_t)nNumBytesRead;
382     return MOS_STATUS_SUCCESS;
383 }
384 
MOS_WriteFile(HANDLE hFile,void * lpBuffer,uint32_t bytesToWrite,uint32_t * pbytesWritten,void * lpOverlapped)385 MOS_STATUS MOS_WriteFile(
386     HANDLE    hFile,
387     void      *lpBuffer,
388     uint32_t  bytesToWrite,
389     uint32_t  *pbytesWritten,
390     void      *lpOverlapped)
391 {
392     size_t    nNumBytesToWrite;
393     ssize_t   nNumBytesWritten;
394     MOS_UNUSED(lpOverlapped);
395 
396     if((hFile == nullptr) || (lpBuffer == nullptr) || (pbytesWritten == nullptr))
397     {
398         return MOS_STATUS_INVALID_PARAMETER;
399     }
400 
401     nNumBytesToWrite = (size_t)bytesToWrite;
402     nNumBytesWritten = 0;
403 
404     //To-do, process lpOverlapped
405 
406     if ((nNumBytesWritten = write((intptr_t)hFile, lpBuffer, nNumBytesToWrite)) < 0)
407     {
408         *pbytesWritten = 0;
409         return MOS_STATUS_FILE_WRITE_FAILED;
410     }
411 
412     *pbytesWritten = (uint32_t)nNumBytesWritten;
413     return MOS_STATUS_SUCCESS;
414 }
415 
MOS_SetFilePointer(HANDLE hFile,int32_t lDistanceToMove,int32_t * lpDistanceToMoveHigh,int32_t dwMoveMethod)416 MOS_STATUS MOS_SetFilePointer(
417     HANDLE        hFile,
418     int32_t       lDistanceToMove,
419     int32_t       *lpDistanceToMoveHigh,
420     int32_t       dwMoveMethod)
421 {
422     int32_t     iOffSet;
423     int32_t     iCurPos;
424 
425     if(hFile == nullptr)
426     {
427         return MOS_STATUS_INVALID_PARAMETER;
428     }
429 
430     if (lpDistanceToMoveHigh == nullptr)
431     {
432         iOffSet = lDistanceToMove;
433     }
434     else
435     {
436         //to-do, let lpDistanceToMoveHigh and lDistanceToMove form a 64-bit iOffSet
437         iOffSet = (int32_t)lDistanceToMove;
438     }
439 
440     if ((iCurPos = lseek((intptr_t)hFile, iOffSet, dwMoveMethod)) < 0)
441     {
442         return MOS_STATUS_SET_FILE_POINTER_FAILED;
443     }
444 
445     return MOS_STATUS_SUCCESS;
446 }
447 
MOS_CloseHandle(HANDLE hObject)448 int32_t MOS_CloseHandle(HANDLE hObject)
449 {
450     int32_t iRet = false;
451 
452     if(hObject != nullptr)
453     {
454         close((intptr_t)hObject);
455         iRet = true;
456     }
457 
458     return iRet;
459 }
460 
461 //library
MOS_LoadLibrary(const char * const lpLibFileName,PHMODULE phModule)462 MOS_STATUS MOS_LoadLibrary(const char * const lpLibFileName, PHMODULE phModule)
463 {
464     if (lpLibFileName == nullptr)
465     {
466         return MOS_STATUS_INVALID_PARAMETER;
467     }
468 
469     *phModule = dlopen((const char *)lpLibFileName, RTLD_LAZY);
470 
471     return ((*phModule != nullptr) ? MOS_STATUS_SUCCESS : MOS_STATUS_LOAD_LIBRARY_FAILED);
472 }
473 
MOS_FreeLibrary(HMODULE hLibModule)474 int32_t MOS_FreeLibrary (HMODULE hLibModule)
475 {
476     uint32_t iRet = 10;   // Initialize to some non-zero value
477 
478     if(hLibModule != nullptr)
479     {
480         iRet = dlclose(hLibModule);
481     }
482     return (iRet == 0) ? true : false;
483 }
484 
MOS_GetProcAddress(HMODULE hModule,const char * lpProcName)485 void  *MOS_GetProcAddress(HMODULE hModule, const char *lpProcName)
486 {
487     void  *pSym = nullptr;
488 
489     if (hModule    == nullptr ||
490         lpProcName == nullptr)
491     {
492         MOS_OS_ASSERTMESSAGE("Invalid parameter.");
493     }
494     else
495     {
496         pSym = dlsym(hModule, lpProcName);
497     }
498 
499     return pSym;
500 }
501 
MOS_GetPid()502 int32_t MOS_GetPid()
503 {
504     return(getpid());
505 }
506 
507 //Performace
MOS_QueryPerformanceFrequency(uint64_t * pFrequency)508 int32_t MOS_QueryPerformanceFrequency(uint64_t *pFrequency)
509 {
510     struct timespec  Res;
511     int32_t          iRet;
512 
513     if(pFrequency == nullptr)
514     {
515         return false;
516     }
517 
518     if ( (iRet = clock_getres(CLOCK_MONOTONIC, &Res)) != 0 )
519     {
520         return false;
521     }
522 
523     // resolution (precision) can't be in seconds for current machine and OS
524     if (Res.tv_sec != 0)
525     {
526         return false;
527     }
528     *pFrequency = (uint64_t)((1000 * 1000 * 1000) / Res.tv_nsec);
529 
530     return true;
531 }
532 
MOS_QueryPerformanceCounter(uint64_t * pPerformanceCount)533 int32_t MOS_QueryPerformanceCounter(uint64_t *pPerformanceCount)
534 {
535     struct timespec     Res;
536     struct timespec     t;
537     int32_t             iRet;
538 
539     if(pPerformanceCount == nullptr)
540     {
541         return false;
542     }
543     if ( (iRet = clock_getres (CLOCK_MONOTONIC, &Res)) != 0 )
544     {
545         return false;
546     }
547     if (Res.tv_sec != 0)
548     { // resolution (precision) can't be in seconds for current machine and OS
549         return false;
550     }
551     if( (iRet = clock_gettime(CLOCK_MONOTONIC, &t)) != 0)
552     {
553         return false;
554     }
555     *pPerformanceCount = (uint64_t)((1000 * 1000 * 1000 * t.tv_sec + t.tv_nsec) / Res.tv_nsec);
556 
557     return true;
558 }
559 
MOS_Sleep(uint32_t mSec)560 void MOS_Sleep(uint32_t mSec)
561 {
562     usleep(1000 * mSec);
563 }
564 
565 //User Feature
566 /*----------------------------------------------------------------------------
567 | Name      : _UserFeature_FindKey
568 | Purpose   : This function finds a key in keys linked list according to key
569 |             name.
570 | Arguments : pKeyList   [in] Key Linked list.
571 |             pcKeyName  [in] Name to the key to find.
572 | Returns   : Matched uf_key data. otherwise return NULL.
573 | Comments  :
574 \---------------------------------------------------------------------------*/
_UserFeature_FindKey(MOS_PUF_KEYLIST pKeyList,char * const pcKeyName)575 static MOS_UF_KEY* _UserFeature_FindKey(MOS_PUF_KEYLIST pKeyList, char * const pcKeyName)
576 {
577     int32_t           iResult;
578     MOS_PUF_KEYLIST   pTempNode;
579 
580     iResult = -1;
581 
582     for(pTempNode = pKeyList; pTempNode; pTempNode = pTempNode->pNext)
583     {
584         iResult = strcmp(pTempNode->pElem->pcKeyName, pcKeyName);
585         if ( iResult == 0 )
586         {
587             return pTempNode->pElem;
588         }
589     }
590     return nullptr; //not found
591 }
592 
593 /*----------------------------------------------------------------------------
594 | Name      : _UserFeature_FindValue
595 | Purpose   : Find a value in values array of a key. Return position in values
596 |             array
597 | Arguments : UFKey        [in] Searched Key node.
598 |             pcValueName  [in] Value name.
599 | Returns   : Matched value No. if it can be found, otherwise, return
600 |             NOT_FOUND(-1);
601 | Comments  :
602 \---------------------------------------------------------------------------*/
_UserFeature_FindValue(MOS_UF_KEY UFKey,char * const pcValueName)603 static int32_t _UserFeature_FindValue(MOS_UF_KEY UFKey, char * const pcValueName)
604 {
605     int32_t iResult;
606     int32_t i;
607 
608     iResult = -1;
609 
610     for ( i = 0; i < (int32_t)UFKey.ulValueNum; i++ )
611     {
612         iResult = strcmp(UFKey.pValueArray[i].pcValueName, pcValueName);
613         if ( iResult == 0 )
614         {
615             return i;
616         }
617     }
618     return NOT_FOUND;
619 }
620 
621 /*----------------------------------------------------------------------------
622 | Name      : _UserFeature_Add
623 | Purpose   : Add new key to keys' linked list.
624 | Arguments : pKeyList       [in] Key linked list.
625 |             NewKey         [in] Added new key.
626 | Returns   : MOS_STATUS_SUCCESS            success
627 |             MOS_STATUS_INVALID_PARAMETER  invalid NewKey
628 |             MOS_STATUS_NO_SPACE           no space left for allocate
629 | Comments  :
630 \---------------------------------------------------------------------------*/
_UserFeature_Add(MOS_PUF_KEYLIST * pKeyList,MOS_UF_KEY * NewKey)631 static MOS_STATUS _UserFeature_Add(MOS_PUF_KEYLIST *pKeyList, MOS_UF_KEY *NewKey)
632 {
633     MOS_UF_KEYNODE  *pNewNode;
634     MOS_UF_KEYNODE  *pTempNode;
635     MOS_UF_KEYNODE  *pStartNode;
636 
637     pNewNode   =  nullptr;
638     pTempNode  =  nullptr;
639     pStartNode =  *pKeyList;
640 
641     if ( NewKey == nullptr )
642     {
643         return MOS_STATUS_INVALID_PARAMETER;
644     }
645 
646     pNewNode = (MOS_UF_KEYNODE*)MOS_AllocMemory(sizeof(MOS_UF_KEYNODE));
647     if (pNewNode == nullptr)
648     {
649         return MOS_STATUS_NO_SPACE;
650     }
651     pNewNode->pElem = NewKey;
652 
653     if (*pKeyList == nullptr ) // the key list is empty
654     {
655         pNewNode->pNext = nullptr;
656         (*pKeyList) = pNewNode;
657     }
658     else // the key list is not empty, append to the front
659     {
660         pTempNode = pStartNode->pNext;
661         pStartNode->pNext = pNewNode;
662         pNewNode->pNext = pTempNode;
663     }
664     return MOS_STATUS_SUCCESS;
665 }
666 
667 /*----------------------------------------------------------------------------
668 | Name      : _UserFeature_Set
669 | Purpose   : This function set a key to the key list.
670 | Arguments : pKeyList          [in] Key linked list.
671 |             NewKey            [in] Set key content.
672 | Returns   : MOS_STATUS_SUCCESS      Operation success.
673 |             MOS_STATUS_UNKNOWN      Can't find key in User Feature File.
674 |             MOS_STATUS_NO_SPACE     no space left for allocate
675 | Comments  :
676 \---------------------------------------------------------------------------*/
_UserFeature_Set(MOS_PUF_KEYLIST * pKeyList,MOS_UF_KEY NewKey)677 static MOS_STATUS _UserFeature_Set(MOS_PUF_KEYLIST *pKeyList, MOS_UF_KEY NewKey)
678 {
679     int32_t       iPos;
680     MOS_UF_VALUE  *pValueArray;
681     MOS_UF_KEY    *Key;
682     void          *ulValueBuf;
683 
684     iPos         = -1;
685     pValueArray  = nullptr;
686 
687     if ( (Key = _UserFeature_FindKey(*pKeyList, NewKey.pcKeyName)) == nullptr )
688     {
689         // can't find key in File
690         return MOS_STATUS_UNKNOWN;
691     }
692 
693     // Prepare the ValueBuff of the NewKey
694     if ((ulValueBuf = MOS_AllocMemory(NewKey.pValueArray[0].ulValueLen)) == nullptr)
695     {
696          return MOS_STATUS_NO_SPACE;
697     }
698 
699     if ( (iPos = _UserFeature_FindValue(*Key, NewKey.pValueArray[0].pcValueName)) == NOT_FOUND)
700     {
701         //not found, add a new value to key struct.
702         //reallocate memory for appending this value.
703         pValueArray = (MOS_UF_VALUE*)MOS_AllocMemory(sizeof(MOS_UF_VALUE)*(Key->ulValueNum+1));
704         if (pValueArray == nullptr)
705         {
706             MOS_FreeMemory(ulValueBuf);
707             return MOS_STATUS_NO_SPACE;
708         }
709 
710         MOS_SecureMemcpy(pValueArray,
711                         sizeof(MOS_UF_VALUE)*(Key->ulValueNum),
712                         Key->pValueArray,
713                         sizeof(MOS_UF_VALUE)*(Key->ulValueNum));
714 
715         MOS_FreeMemory(Key->pValueArray);
716 
717         Key->pValueArray = pValueArray;
718 
719         iPos = Key->ulValueNum;
720         MOS_SecureStrcpy(Key->pValueArray[Key->ulValueNum].pcValueName,
721             MAX_USERFEATURE_LINE_LENGTH,
722             NewKey.pValueArray[0].pcValueName);
723         Key->ulValueNum ++;
724     }
725     else
726     {
727         //if found, the previous value buffer needs to be freed before reallocating
728         MOS_FreeMemory(Key->pValueArray[iPos].ulValueBuf);
729     }
730 
731     Key->pValueArray[iPos].ulValueLen  = NewKey.pValueArray[0].ulValueLen;
732     Key->pValueArray[iPos].ulValueType = NewKey.pValueArray[0].ulValueType;
733     Key->pValueArray[iPos].ulValueBuf  = ulValueBuf;
734 
735     MOS_ZeroMemory(Key->pValueArray[iPos].ulValueBuf, NewKey.pValueArray[0].ulValueLen);
736 
737     MOS_SecureMemcpy(Key->pValueArray[iPos].ulValueBuf,
738                      NewKey.pValueArray[0].ulValueLen,
739                      NewKey.pValueArray[0].ulValueBuf,
740                      NewKey.pValueArray[0].ulValueLen);
741 
742     return MOS_STATUS_SUCCESS;
743 }
744 
745 /*----------------------------------------------------------------------------
746 | Name      : _UserFeature_Query
747 | Purpose   : This function query a key's value and return matched key node
748 |             content just with matched value content.
749 | Arguments : pKeyList      [in] Key linked list.
750 |             NewKey        [in] New key content with matched value.
751 | Returns   : MOS_STATUS_SUCCESS         Operation success.
752 |             MOS_STATUS_UNKNOWN         Can't find key or value in User Feature File.
753 | Comments  :
754 \---------------------------------------------------------------------------*/
_UserFeature_Query(MOS_PUF_KEYLIST pKeyList,MOS_UF_KEY * NewKey)755 static MOS_STATUS _UserFeature_Query(MOS_PUF_KEYLIST pKeyList, MOS_UF_KEY *NewKey)
756 {
757     int32_t       iPos;
758     MOS_UF_VALUE  *pValueArray;
759     MOS_UF_KEY    *Key;
760 
761     iPos         = -1;
762     pValueArray  = nullptr;
763 
764     // can't find key in user feature
765     if ( (Key = _UserFeature_FindKey(pKeyList, NewKey->pcKeyName)) == nullptr )
766     {
767         return MOS_STATUS_UNKNOWN;
768     }
769 
770     // can't find Value in the key
771     if ( (iPos = _UserFeature_FindValue(*Key, NewKey->pValueArray[0].pcValueName)) == NOT_FOUND)
772     {
773         return MOS_STATUS_UNKNOWN;
774     }
775 
776     //get key content from user feature
777     MOS_SecureMemcpy(NewKey->pValueArray[0].ulValueBuf,
778                      Key->pValueArray[iPos].ulValueLen,
779                      Key->pValueArray[iPos].ulValueBuf,
780                      Key->pValueArray[iPos].ulValueLen);
781 
782     NewKey->pValueArray[0].ulValueLen    =  Key->pValueArray[iPos].ulValueLen;
783     NewKey->pValueArray[0].ulValueType   =  Key->pValueArray[iPos].ulValueType;
784 
785     return MOS_STATUS_SUCCESS;
786 }
787 
_UserFeature_ReadNextTokenFromFile(FILE * pFile,const char * szFormat,char * szToken)788 static MOS_STATUS _UserFeature_ReadNextTokenFromFile(FILE *pFile, const char *szFormat, char  *szToken)
789 {
790     size_t nTokenSize = 0;
791 
792     // Reads the next token from the given pFile.
793     if (fscanf(pFile, szFormat, szToken) <= 0)
794     {
795         MOS_OS_VERBOSEMESSAGE("Failed reading the next token from the user feature file. This is probably because the token does not exist in the user feature file.");
796         return MOS_STATUS_FILE_READ_FAILED;
797     }
798 
799     // Converts to Unix-style line endings to prevent compatibility problems.
800     nTokenSize = strnlen(szToken, MAX_USERFEATURE_LINE_LENGTH);
801     if (szToken[nTokenSize-1] == '\r')
802     {
803         szToken[nTokenSize-1] = '\0';
804     }
805 
806     return MOS_STATUS_SUCCESS;
807 }
808 
809 /*----------------------------------------------------------------------------
810 | Name      : _UserFeature_DumpFile
811 | Purpose   : This function read the whole User Feature File and dump User Feature File
812 |             data to key linked list.
813 | Arguments : szFileName         [in]  User Feature File name.
814 |             pKeyList           [out] Key Linked list.
815 | Returns   : MOS_STATUS_SUCCESS           Operation success.
816 |             MOS_STATUS_USER_FEATURE_KEY_READ_FAILED  User Feature File can't be open as read.
817 |             MOS_STATUS_NO_SPACE          no space left for allocate
818 |             MOS_STATUS_UNKNOWN           unknown user feature type found in User Feature File
819 |             MOS_STATUS_INVALID_PARAMETER unknown items found in User Feature File
820 | Comments  :
821 \---------------------------------------------------------------------------*/
_UserFeature_DumpFile(const char * const szFileName,MOS_PUF_KEYLIST * pKeyList)822 static MOS_STATUS _UserFeature_DumpFile(const char * const szFileName, MOS_PUF_KEYLIST* pKeyList)
823 {
824     MOS_UF_KEY      *CurKey;
825     MOS_UF_VALUE    *CurValue;
826     char            szTmp[MAX_USERFEATURE_LINE_LENGTH];
827     int32_t         iResult;
828     size_t          nSize;
829     int32_t         bFirst;
830     int32_t         iCount;
831     PFILE           File;
832     int32_t         bEmpty;
833     int32_t         iCurId;
834     MOS_STATUS      eStatus;
835     char            *tmpChar; // Used in the 64-bit case to read uint64_t
836 
837     CurValue  =  nullptr;
838     nSize     =  0;
839     bFirst    =  1;    // 1 stand for "is the first key".
840     iCount    =  0;
841     File      =  nullptr;
842     bEmpty    =  0;
843     iCurId    =  0;
844     eStatus  =  MOS_STATUS_SUCCESS;
845 
846     CurKey = (MOS_UF_KEY*)MOS_AllocMemory(sizeof(MOS_UF_KEY));
847     if (CurKey == nullptr)
848     {
849         return MOS_STATUS_NO_SPACE;
850     }
851     CurKey->ulValueNum       = 0;
852     CurKey->pcKeyName[0]    = '\0';
853     CurKey->pValueArray       = nullptr;
854 
855     if ( (File = fopen(szFileName, "r")) == nullptr)
856     {
857         MOS_FreeMemory(CurKey);
858         return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
859     }
860     while (feof(File) != EOF)
861     {
862         MOS_ZeroMemory(szTmp, MAX_USERFEATURE_LINE_LENGTH*sizeof(char ));
863         if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
864         {
865             break;
866         }
867 
868         // set szDumpData with extracted File content.
869         iResult = strcmp(szTmp, UF_KEY_ID);
870         if ( iResult == 0 )
871         {
872             // It is a new key starting!
873             if (! bFirst )
874             {
875                 // Add last key struct to contents when the key is not first.
876                 // otherwise, continue to load key struct data.
877                 CurKey->pValueArray   = CurValue;
878                 CurKey->ulValueNum   = iCount;
879                 if(_UserFeature_Add(pKeyList, CurKey) != MOS_STATUS_SUCCESS)
880                 {
881                     // if the CurKey didn't be added in pKeyList, free it.
882                     MOS_FreeMemory(CurKey);
883                 }
884                 CurKey = (MOS_UF_KEY*)MOS_AllocMemory(sizeof(MOS_UF_KEY));
885                 if (CurKey == nullptr)
886                 {
887                     eStatus = MOS_STATUS_NO_SPACE;
888                     break;
889                 }
890             } // if (! bFirst )
891 
892             if (fscanf(File, "%x\n", &iCurId) <= 0)
893             {
894                 break;
895             }
896 
897             CurKey->UFKey = (void *)(intptr_t)iCurId;
898 
899             MOS_ZeroMemory(szTmp, MAX_USERFEATURE_LINE_LENGTH * sizeof(char));
900             if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
901             {
902                 break;
903             }
904 
905             MOS_SecureStrcpy(CurKey->pcKeyName, MAX_USERFEATURE_LINE_LENGTH, szTmp);
906             CurKey->ulValueNum = 0;
907 
908             // allocate capability length for valuearray.
909             CurValue = (MOS_UF_VALUE*)MOS_AllocMemory(sizeof(MOS_UF_VALUE)*UF_CAPABILITY);
910             if (CurValue == nullptr)
911             {
912                 eStatus = MOS_STATUS_NO_SPACE;
913                 break;
914             }
915             bFirst = 0;
916             iCount = 0;  // next key's array number.
917             bEmpty = 1;
918         } // if ( iResult == 0 )
919         else // not a key
920         {
921             // Is it a value starting?
922             iResult = strcmp(szTmp, UF_VALUE_ID);
923             if ( iResult == 0 )
924             {
925                 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
926                 {
927                     break;
928                 }
929 
930                 if (CurValue == nullptr)
931                 {
932                     break;
933                 }
934 
935                 // Out of bounds technically based on how much memory we allocated
936                 if (iCount < 0 || iCount >= UF_CAPABILITY)
937                 {
938                     eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
939                     break;
940                 }
941 
942                 // Load value name;
943                 MOS_SecureStrcpy(CurValue[iCount].pcValueName, MAX_USERFEATURE_LINE_LENGTH, szTmp);
944 
945                 // Load value type
946                 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
947                 {
948                     break;
949                 }
950 
951                 CurValue[iCount].ulValueType = atoi(szTmp);
952 
953                 // Load value buffer.
954                 switch ( CurValue[iCount].ulValueType )
955                 {
956                 case UF_DWORD: // 32-bit
957                     if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
958                     {
959                         break;
960                     }
961 
962                     CurValue[iCount].ulValueLen = sizeof(uint32_t);
963                     CurValue[iCount].ulValueBuf = MOS_AllocMemory(sizeof(uint32_t));
964                     if(CurValue[iCount].ulValueBuf == nullptr)
965                     {
966                         eStatus = MOS_STATUS_NO_SPACE;
967                         break;
968                     }
969                     *(uint32_t*)(CurValue[iCount].ulValueBuf) = atoi(szTmp);
970                     break;
971                 case UF_QWORD: // 64-bit
972                     if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
973                     {
974                         break;
975                     }
976 
977                     CurValue[iCount].ulValueLen = sizeof(uint64_t);
978                     CurValue[iCount].ulValueBuf = MOS_AllocMemory(sizeof(uint64_t));
979                     if(CurValue[iCount].ulValueBuf == nullptr)
980                     {
981                         eStatus = MOS_STATUS_NO_SPACE;
982                         break;
983                     }
984                     tmpChar = &szTmp[0];
985                     *(uint64_t*)(CurValue[iCount].ulValueBuf) = strtoll(tmpChar,&tmpChar,0);
986                     break;
987                 case UF_SZ:
988                 case UF_MULTI_SZ:
989                     if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
990                     {
991                         break;
992                     }
993 
994                     nSize = strlen(szTmp);
995                     CurValue[iCount].ulValueLen = (nSize+1)*sizeof(char );
996                     CurValue[iCount].ulValueBuf = MOS_AllocMemory(nSize+1);
997                     if(CurValue[iCount].ulValueBuf == nullptr)
998                     {
999                         eStatus = MOS_STATUS_NO_SPACE;
1000                         break;
1001                     }
1002                     MOS_ZeroMemory(CurValue[iCount].ulValueBuf, nSize+1);
1003                     MOS_SecureMemcpy(CurValue[iCount].ulValueBuf, nSize, szTmp, nSize);
1004                     break;
1005                 default:
1006                     eStatus = MOS_STATUS_UNKNOWN;
1007                 }
1008                 if (eStatus != MOS_STATUS_SUCCESS)
1009                 {
1010                     break;
1011                 }
1012 
1013                 iCount ++; // do the error checking near the top
1014 
1015             } // if ( iResult == 0 )
1016             else   // It is not a value starting, it's bad User Feature File.
1017             {
1018                 int32_t iResult = strcmp(szTmp, "");
1019                 if ( !iResult )
1020                 {
1021                     continue;
1022                 }
1023                 else
1024                 {
1025                     eStatus =  MOS_STATUS_INVALID_PARAMETER;
1026                     break;
1027                 }
1028             } // else ( iResult == 0 )
1029         }
1030     } // while (feof(File) != EOF)
1031 
1032     if (eStatus == MOS_STATUS_SUCCESS)
1033     {
1034         if ( bEmpty && (strlen(CurKey->pcKeyName) > 0) &&
1035             (CurKey->ulValueNum == 0) )
1036         {
1037             CurKey->pValueArray   = CurValue;
1038             CurKey->ulValueNum   = iCount;
1039             if(_UserFeature_Add(pKeyList, CurKey) != MOS_STATUS_SUCCESS)
1040             {
1041                 // if the CurKey didn't be added in pKeyList, free it.
1042                 for (uint32_t i = 0; i < iCount; i++)
1043                 {
1044                     if (CurValue)
1045                     {
1046                         MOS_FreeMemory(CurValue[i].ulValueBuf);
1047                     }
1048                 }
1049                 MOS_FreeMemory(CurValue);
1050                 MOS_FreeMemory(CurKey);
1051             }
1052         }
1053         else
1054         {
1055             for (uint32_t i = 0; i < iCount; i++)
1056             {
1057                 if (CurValue)
1058                 {
1059                     MOS_FreeMemory(CurValue[i].ulValueBuf);
1060                 }
1061             }
1062             MOS_FreeMemory(CurValue);
1063             MOS_FreeMemory(CurKey);
1064         }
1065     }
1066     else
1067     {
1068         for (uint32_t i = 0; i < iCount; i++)
1069         {
1070             if (CurValue)
1071             {
1072                 MOS_FreeMemory(CurValue[i].ulValueBuf);
1073             }
1074         }
1075         MOS_FreeMemory(CurValue);
1076         MOS_FreeMemory(CurKey);
1077     }
1078     fclose(File);
1079     return eStatus;
1080 }
1081 
1082 /*----------------------------------------------------------------------------
1083 | Name      : _UserFeature_DumpDataToFile
1084 | Purpose   : This function dump key linked list data to File.
1085 | Arguments : szFileName             [in] A handle to the File.
1086 |             pKeyList               [in] Reserved, any LPDWORD type value.
1087 | Returns   : MOS_STATUS_SUCCESS                        Operation success.
1088 |             MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED  File can't be written.
1089 | Comments  :
1090 \---------------------------------------------------------------------------*/
_UserFeature_DumpDataToFile(const char * szFileName,MOS_PUF_KEYLIST pKeyList)1091 static MOS_STATUS _UserFeature_DumpDataToFile(const char *szFileName, MOS_PUF_KEYLIST pKeyList)
1092 {
1093     int32_t           iResult;
1094     PFILE             File;
1095     MOS_PUF_KEYLIST   pKeyTmp;
1096     int32_t           j;
1097 
1098     File = fopen(szFileName, "w+");
1099     if ( !File )
1100     {
1101         return MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
1102     }
1103 
1104     for (pKeyTmp = pKeyList; pKeyTmp; pKeyTmp = pKeyTmp->pNext)
1105     {
1106         fprintf(File, "%s\n", UF_KEY_ID);
1107         fprintf(File,  "\t0x%.8x\n", (uint32_t)(uintptr_t)pKeyTmp->pElem->UFKey);
1108         fprintf(File,  "\t%s\n", pKeyTmp->pElem->pcKeyName);
1109         for ( j = 0; j < (int32_t)pKeyTmp->pElem->ulValueNum; j ++ )
1110         {
1111             fprintf(File, "\t\t%s\n", UF_VALUE_ID);
1112             if ( strlen(pKeyTmp->pElem->pValueArray[j].pcValueName) > 0 )
1113             {
1114                 fprintf(File, "\t\t\t%s\n",
1115                     pKeyTmp->pElem->pValueArray[j].pcValueName);
1116             }
1117             fprintf(File, "\t\t\t%d\n", pKeyTmp->pElem->pValueArray[j].ulValueType);
1118             if (pKeyTmp->pElem->pValueArray[j].ulValueBuf != nullptr)
1119             {
1120                 switch (pKeyTmp->pElem->pValueArray[j].ulValueType)
1121                 {
1122                 case UF_SZ:
1123                     fprintf(File,  "\t\t\t%s\n",
1124                         (char *)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1125                     break;
1126                 case UF_DWORD:
1127                 case UF_QWORD:
1128                     fprintf(File, "\t\t\t%d\n",
1129                         *(uint32_t*)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1130                     break;
1131                 default:
1132                     fprintf(File, "\t\t\t%s\n",
1133                         (char *)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1134                     break;
1135                 } //switch (pKeyTmp->pElem->pValueArray[j].ulValueType)
1136             }
1137         } // for ( j = 0; j < (int32_t)pKeyTmp->pElem->ulValueNum; j ++ )
1138     } //for (pKeyTmp = pKeyList; pKeyTmp; pKeyTmp = pKeyTmp->pNext)
1139     fclose(File);
1140     MOS_UserFeatureNotifyChangeKeyValue(nullptr, false, nullptr, true);
1141 
1142     return MOS_STATUS_SUCCESS;
1143 }
1144 
1145 /*----------------------------------------------------------------------------
1146 | Name      : _UserFeature_FreeKeyList
1147 | Purpose   : Free key list
1148 | Arguments : pKeyList           [in] key list to be free.
1149 | Returns   : None
1150 | Comments  :
1151 \---------------------------------------------------------------------------*/
_UserFeature_FreeKeyList(MOS_PUF_KEYLIST pKeyList)1152 static void _UserFeature_FreeKeyList(MOS_PUF_KEYLIST pKeyList)
1153 {
1154     MOS_PUF_KEYLIST     pKeyTmp;
1155     MOS_PUF_KEYLIST     pKeyTmpNext;
1156     uint32_t            i;
1157 
1158     pKeyTmp = pKeyList;
1159     while(pKeyTmp)
1160     {
1161         pKeyTmpNext = pKeyTmp->pNext;
1162         for(i=0;i<pKeyTmp->pElem->ulValueNum;i++)
1163         {
1164             MOS_FreeMemory(pKeyTmp->pElem->pValueArray[i].ulValueBuf);
1165         }
1166         MOS_FreeMemory(pKeyTmp->pElem->pValueArray);
1167         MOS_FreeMemory(pKeyTmp->pElem);
1168         MOS_FreeMemory(pKeyTmp);
1169         pKeyTmp = pKeyTmpNext;
1170     }
1171     return;
1172 }
1173 
1174 /*----------------------------------------------------------------------------
1175 | Name      : _UserFeature_SetValue
1176 | Purpose   : Modify or add a value of the specified user feature key.
1177 | Arguments : strKey         [in] Pointer to user feature key name.
1178 |             pcValueName    [in] Pointer to a string containing the name of
1179 |                                 the value to set. If a value with this name
1180 |                                 is not already present in the key, the
1181 |                                 function adds it to the key.
1182 |             uiValueType    [in] Type of information to be stored.
1183 |             szValueData    [in] Pointer to a null-terminated string
1184 |                                 containing the data to set for the default
1185 |                                 value of the specified key
1186 |             uiValueDataLen [in] Size of the string pointed to by the
1187 |                                 szValueData parameter, not including the
1188 |                                 terminating null character, in bytes
1189 | Returns   : MOS_STATUS_SUCCESS           function success
1190 |             MOS_STATUS_INVALID_PARAMETER invalid paramater
1191 |             MOS_STATUS_USER_FEATURE_KEY_READ_FAILED  User Feature File can't be open as read.
1192 |             MOS_STATUS_NO_SPACE          no space left for allocate
1193 |             MOS_STATUS_UNKNOWN           unknown user feature type found in User Feature File
1194 |             MOS_STATUS_INVALID_PARAMETER unknown items found in User Feature File
1195 |             MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED  User Feature File can't be written.
1196 | Comments  :
1197 \---------------------------------------------------------------------------*/
_UserFeature_SetValue(char * const strKey,const char * const pcValueName,uint32_t uiValueType,void * pData,int32_t nDataSize)1198 static MOS_STATUS _UserFeature_SetValue(
1199     char * const        strKey,
1200     const char * const  pcValueName,
1201     uint32_t            uiValueType,
1202     void                *pData,
1203     int32_t             nDataSize)
1204 {
1205     MOS_UF_KEY          NewKey;
1206     MOS_UF_VALUE        NewValue;
1207     MOS_STATUS          eStatus;
1208     MOS_PUF_KEYLIST     pKeyList;
1209 
1210     eStatus   = MOS_STATUS_UNKNOWN;
1211     pKeyList   = nullptr;
1212 
1213     if ( (strKey== nullptr) || (pcValueName == nullptr) )
1214     {
1215         return MOS_STATUS_INVALID_PARAMETER;
1216     }
1217 
1218     MOS_ZeroMemory(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH);
1219     MOS_SecureStrcpy(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH, pcValueName);
1220     NewValue.ulValueType    = uiValueType;
1221     if( NewValue.ulValueType == UF_DWORD)
1222     {
1223         NewValue.ulValueLen = sizeof(uint32_t);
1224     }
1225     else
1226     {
1227         NewValue.ulValueLen = nDataSize;
1228     }
1229     NewValue.ulValueBuf     = pData;
1230 
1231     MOS_ZeroMemory(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH);
1232     MOS_SecureStrcpy(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH, strKey);
1233     NewKey.pValueArray = &NewValue;
1234     NewKey.ulValueNum = 1;
1235 
1236     if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) != MOS_STATUS_SUCCESS )
1237     {
1238         MOS_FreeMemory(pKeyList);
1239         return eStatus;
1240     }
1241 
1242     if ( ( eStatus = _UserFeature_Set(&pKeyList, NewKey)) == MOS_STATUS_SUCCESS )
1243     {
1244         eStatus = _UserFeature_DumpDataToFile(szUserFeatureFile, pKeyList);
1245     }
1246 
1247     _UserFeature_FreeKeyList(pKeyList);
1248     return eStatus;
1249 }
1250 
1251 /*----------------------------------------------------------------------------
1252 | Name      : _UserFeature_QueryValue
1253 | Purpose   : The QueryValue function retrieves the type and data for a
1254 |             specified value name associated with a special user feature key.
1255 | Arguments : strKey         [in]  Pointer to user feature key name.
1256 |             pcValueName    [in]  Pointer to a string containing the name
1257 |                                  of the value to query.
1258 |             uiValueType    [out] Output Value's type
1259 |             pData          [out] Output value's content
1260 |             nDataSize      [out] Output the size of value's content.
1261 | Returns   : MOS_STATUS_SUCCESS           function success
1262 |             MOS_STATUS_INVALID_PARAMETER invalid paramater
1263 |             MOS_STATUS_USER_FEATURE_KEY_READ_FAILED  User Feature File can't be open as read.
1264 |             MOS_STATUS_NO_SPACE          no space left for allocate
1265 |             MOS_STATUS_UNKNOWN           Can't find key or value in User Feature File.
1266 | Comments  :
1267 \---------------------------------------------------------------------------*/
_UserFeature_QueryValue(char * const strKey,const char * const pcValueName,uint32_t * uiValueType,void * pData,int32_t * nDataSize)1268 static MOS_STATUS _UserFeature_QueryValue(
1269     char * const        strKey,
1270     const char * const  pcValueName,
1271     uint32_t            *uiValueType,
1272     void                *pData,
1273     int32_t             *nDataSize)
1274 {
1275     MOS_UF_KEY          NewKey;
1276     MOS_UF_VALUE        NewValue;
1277     size_t              nKeyLen, nValueLen;
1278     MOS_STATUS          eStatus;
1279     MOS_PUF_KEYLIST     pKeyList;
1280     char                strTempKey[MAX_USERFEATURE_LINE_LENGTH];
1281     char                strTempValueName[MAX_USERFEATURE_LINE_LENGTH];
1282 
1283     eStatus   = MOS_STATUS_UNKNOWN;
1284     pKeyList   = nullptr;
1285 
1286     if ( (strKey == nullptr) || (pcValueName == nullptr))
1287     {
1288         return MOS_STATUS_INVALID_PARAMETER;
1289     }
1290     MOS_ZeroMemory(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH);
1291     MOS_SecureStrcpy(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH, pcValueName);
1292     NewValue.ulValueBuf     = pData;
1293 
1294     MOS_ZeroMemory(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH);
1295     MOS_SecureStrcpy(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH, strKey);
1296     NewKey.pValueArray = &NewValue;
1297     NewKey.ulValueNum = 1;
1298 
1299     if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) == MOS_STATUS_SUCCESS)
1300     {
1301         if ( (eStatus = _UserFeature_Query(pKeyList, &NewKey)) == MOS_STATUS_SUCCESS )
1302         {
1303             if(uiValueType != nullptr)
1304             {
1305                 *uiValueType = NewKey.pValueArray[0].ulValueType;
1306             }
1307             if (nDataSize != nullptr)
1308             {
1309                 *nDataSize   = NewKey.pValueArray[0].ulValueLen;
1310             }
1311         }
1312     }
1313     _UserFeature_FreeKeyList(pKeyList);
1314 
1315     return eStatus;
1316 }
1317 
1318 /*----------------------------------------------------------------------------
1319 | Name      : _UserFeature_GetKeyIdbyName
1320 | Purpose   : Get ID of the user feature key bu its name
1321 | Arguments : pcKeyName      [in]  Pointer to user feature key name.
1322 |             pUFKey         [out] A UFKEY pointer to store returned UFKey
1323 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1324 |             If the function fails, the return value is a error code defined
1325 |             in mos_utilities.h.
1326 | Comments  :
1327 \---------------------------------------------------------------------------*/
_UserFeature_GetKeyIdbyName(const char * pcKeyName,void ** pUFKey)1328 static MOS_STATUS _UserFeature_GetKeyIdbyName(const char  *pcKeyName, void **pUFKey)
1329 {
1330     MOS_PUF_KEYLIST     pKeyList;
1331     int32_t             iResult;
1332     MOS_STATUS          eStatus;
1333     MOS_PUF_KEYLIST     pTempNode;
1334 
1335     pKeyList   = nullptr;
1336     iResult    = -1;
1337 
1338     if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) !=
1339         MOS_STATUS_SUCCESS )
1340     {
1341         MOS_FreeMemory(pKeyList);
1342         return eStatus;
1343     }
1344 
1345     eStatus   = MOS_STATUS_INVALID_PARAMETER;
1346 
1347     for(pTempNode=pKeyList; pTempNode; pTempNode=pTempNode->pNext)
1348     {
1349         iResult = strcmp(pTempNode->pElem->pcKeyName, pcKeyName);
1350         if ( iResult == 0 )
1351         {
1352             *pUFKey = pTempNode->pElem->UFKey;
1353             eStatus = MOS_STATUS_SUCCESS;
1354             break;
1355         }
1356     }
1357     _UserFeature_FreeKeyList(pKeyList);
1358 
1359     return eStatus;
1360 }
1361 
1362 /*----------------------------------------------------------------------------
1363 | Name      : _UserFeature_GetKeyNamebyId
1364 | Purpose   : Get name of the user feature key bu its ID
1365 | Arguments : UFKey      [in]  ID of the user feature key
1366 |             pcKeyName  [out] To store user feature key name.
1367 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1368 |             If the function fails, the return value is a error code defined
1369 |             in mos_utilities.h.
1370 | Comments  :
1371 \---------------------------------------------------------------------------*/
_UserFeature_GetKeyNamebyId(void * UFKey,char * pcKeyName)1372 static MOS_STATUS _UserFeature_GetKeyNamebyId(void  *UFKey, char  *pcKeyName)
1373 {
1374     MOS_PUF_KEYLIST     pKeyList;
1375     MOS_PUF_KEYLIST     pTempNode;
1376     MOS_STATUS          eStatus;
1377 
1378     pKeyList   = nullptr;
1379 
1380     switch((uintptr_t)UFKey)
1381     {
1382     case UFKEY_INTERNAL:
1383         MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_INTERNAL);
1384         eStatus = MOS_STATUS_SUCCESS;
1385         break;
1386     case UFKEY_EXTERNAL:
1387         MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_EXTERNAL);
1388         eStatus = MOS_STATUS_SUCCESS;
1389         break;
1390     default:
1391         if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) !=
1392             MOS_STATUS_SUCCESS )
1393         {
1394             MOS_FreeMemory(pKeyList);
1395             return eStatus;
1396         }
1397 
1398         eStatus   = MOS_STATUS_UNKNOWN;
1399 
1400         for(pTempNode=pKeyList;pTempNode;pTempNode=pTempNode->pNext)
1401         {
1402             if(pTempNode->pElem->UFKey == UFKey)
1403             {
1404                 MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, pTempNode->pElem->pcKeyName);
1405                 eStatus = MOS_STATUS_SUCCESS;
1406                 break;
1407             }
1408         }
1409         _UserFeature_FreeKeyList(pKeyList);
1410         break;
1411     }
1412 
1413     return eStatus;
1414 
1415 }
1416 
1417 /*----------------------------------------------------------------------------
1418 | Name      : MOS_CheckMountStatus
1419 | Purpose   : check mount status
1420 | Arguments : pKeyWord   [in]  Keyword for the Mountpoint
1421 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1422 |             If the function fails, the return value is a error code defined
1423 |             in mos_utilities.h.
1424 | Comments  :
1425 \---------------------------------------------------------------------------*/
MOS_CheckMountStatus(char * pKeyWord)1426 MOS_STATUS MOS_CheckMountStatus(char  *pKeyWord)
1427 {
1428     char        sPartitionPath[MAX_UF_PATH] = {'\0'};
1429     char        sMountPoint[MAX_UF_PATH] = {'\0'};
1430     char        sSystemType[MAX_UF_PATH] = {'\0'};
1431     char        sTemp0[MAX_UF_PATH] = {'\0'};
1432     char        sTemp1[MAX_UF_PATH] = {'\0'};
1433     char        sTemp2[MAX_UF_PATH] = {'\0'};
1434     FILE*       file;
1435     MOS_STATUS  eStatus = MOS_STATUS_UNKNOWN;
1436 
1437     file = fopen("/proc/mounts", "r");
1438     MOS_OS_CHK_NULL(file);
1439     MOS_OS_CHK_NULL(pKeyWord);
1440 
1441     while( fscanf( file, "%255s %255s %255s %255s %255s %255s\n", sPartitionPath, sMountPoint, sSystemType, sTemp0, sTemp1, sTemp2 ) > 0 )
1442     {
1443         if( strcmp(sSystemType, pKeyWord) == 0 )
1444         {
1445             eStatus = MOS_STATUS_SUCCESS;
1446             break;
1447         }
1448         if( strcmp(sMountPoint, pKeyWord) == 0 )
1449         {
1450             eStatus = MOS_STATUS_SUCCESS;
1451             break;
1452         }
1453     }
1454 finish:
1455     if (file != nullptr)
1456     {
1457         fclose(file);
1458     }
1459     return eStatus;
1460 }
1461 #ifdef ANDROID
1462 /*----------------------------------------------------------------------------
1463 | Name      : MOS_Strip_Chars
1464 | Purpose   : Strip some characters from a string
1465 | Arguments : pstorestr  [out] To store a striped string.
1466 |             pstring    [in]  string needed to be striped.
1467 |             pchars     [in]  stripped keyword.
1468 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1469 |             If the function fails, the return value is an error code defined
1470 |             in mos_utilities.h.
1471 | Comments  :
1472 \---------------------------------------------------------------------------*/
MOS_StripChars(char * pstorestr,const char * pstring,const char * pchars)1473 MOS_STATUS MOS_StripChars(char  *pstorestr, const char *pstring, const char *pchars)
1474 {
1475     int32_t       counter = 0;
1476     MOS_STATUS    eStatus = MOS_STATUS_SUCCESS;
1477 
1478     MOS_OS_CHK_NULL(pstring);
1479     MOS_OS_CHK_NULL(pchars);
1480 
1481     for ( ; *pstring; pstring++)
1482     {
1483         if (!strchr(pchars, *pstring))
1484         {
1485             pstorestr[ counter ] = *pstring;
1486             ++ counter;
1487         }
1488     }
1489     pstorestr[counter] = 0;
1490 finish:
1491     return eStatus;
1492 }
1493 
1494 /*----------------------------------------------------------------------------
1495 | Name      : MOS_InitAndroidPropInfo
1496 | Purpose   : Init Android Property Info
1497 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1498 |             If the function fails, the return value is a error code defined
1499 |             in mos_utilities.h.
1500 | Comments  :
1501 \---------------------------------------------------------------------------*/
MOS_InitAndroidPropInfo()1502 MOS_STATUS MOS_InitAndroidPropInfo()
1503 {
1504     char                            prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1505     MOS_STATUS                      eStatus = MOS_STATUS_UNKNOWN;
1506     int32_t                         ret;
1507     int32_t                         iUFKeyEnable;
1508     MOS_USER_FEATURE_VALUE_DATA     UserFeatureData;
1509 
1510     eStatus = MOS_CheckMountStatus((char *)"/system");
1511     if (eStatus == MOS_STATUS_SUCCESS)
1512     {
1513         eStatus = MOS_STATUS_UNKNOWN;
1514         if (property_get("debug.LibVa.RegKeyEnable", prop, nullptr) > 0)
1515         {
1516             if (sscanf(prop, "%d\n", &iUFKeyEnable) > 0)
1517             {
1518                 if (iUFKeyEnable == 1)
1519                 {
1520                     eStatus = MOS_STATUS_SUCCESS;
1521                 }
1522             }
1523         }
1524     }
1525     return eStatus;
1526 }
1527 
1528 /*----------------------------------------------------------------------------
1529 | Name      : MOS_GetAndroidPropPath
1530 | Purpose   : get AndroidProp path
1531 | Arguments : pPath         [out] store the path
1532 |             pUserFeature  [in]  User Feature data for input User Feature Key
1533 |             FuncType      [in]  Read/Write Type
1534 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1535 |             If the function fails, the return value is a error code defined
1536 |             in mos_utilities.h.
1537 | Comments  :
1538 \---------------------------------------------------------------------------*/
MOS_GetAndroidPropPath(char * pPath,PMOS_USER_FEATURE_VALUE pUserFeature,LINUX_UF_FUNC_TYPE FuncType)1539 MOS_STATUS MOS_GetAndroidPropPath(
1540     char                        *pPath,
1541     PMOS_USER_FEATURE_VALUE     pUserFeature,
1542     LINUX_UF_FUNC_TYPE          FuncType)
1543 {
1544 
1545     char        sPath[MAX_UF_PATH];
1546     char        sKey[MAX_UF_PATH];
1547     char        sFuncType[MAX_UF_PATH];
1548     char        pPrefixPath[MAX_UF_PATH];
1549     char        sUFName[MAX_UF_PATH];
1550     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
1551     MOS_OS_CHK_NULL(pUserFeature);
1552     MOS_OS_CHK_NULL(pPath);
1553 
1554     MOS_ZeroMemory(sPath, MAX_UF_PATH);
1555     MOS_ZeroMemory(sKey,  MAX_UF_PATH);
1556     switch(pUserFeature->Type)
1557     {
1558     case MOS_USER_FEATURE_TYPE_USER:
1559         MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFINT_PATH_LINUX);
1560         break;
1561     case MOS_USER_FEATURE_TYPE_SYSTEM:
1562         MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFEXT_PATH_LINUX);
1563         break;
1564     default:
1565         MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFINT_PATH_LINUX);
1566         break;
1567     }// switch
1568 
1569     MOS_ZeroMemory(sFuncType, MAX_UF_PATH);
1570     switch(FuncType)
1571     {
1572     case LINUX_UF_FUNCTYPE_READ:
1573         MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcPath);
1574         break;
1575     case LINUX_UF_FUNCTYPE_WRITE:
1576         MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcWritePath);
1577         break;
1578     default:
1579         MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcPath);
1580         break;
1581     }// switch
1582 
1583     MOS_OS_CHK_STATUS(MOS_StripChars(sUFName,pUserFeature->pValueName," "));
1584     snprintf(
1585         sPath,
1586         sizeof(sPath),
1587         "%s.%s.%s",
1588         sKey,
1589         sFuncType,
1590         sUFName);
1591 
1592     MOS_SecureMemcpy(pPath, strlen(sPath)+1, sPath, strlen(sPath)+1);
1593 finish:
1594     return eStatus;
1595 }
1596 
1597 /*----------------------------------------------------------------------------
1598 | Name      : MOS_AndroidPropOpenKey
1599 | Purpose   : open a file for AndroidProp
1600 | Arguments : pPath       [in]
1601 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1602 |             If the function fails, the return value is a error code defined
1603 |             in mos_utilities.h.
1604 | Comments  :
1605 \---------------------------------------------------------------------------*/
MOS_AndroidPropOpenKey(char * pPath)1606 MOS_STATUS MOS_AndroidPropOpenKey(
1607     char                *pPath)
1608 {
1609     MOS_STATUS      eStatus = MOS_STATUS_FILE_OPEN_FAILED;
1610     char            prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1611     MOS_OS_CHK_NULL(pPath);
1612 
1613     if (property_get(pPath, prop, nullptr) > 0)
1614     {
1615         eStatus = MOS_STATUS_SUCCESS;
1616     }
1617 finish:
1618     return eStatus;
1619 }
1620 
1621 /*----------------------------------------------------------------------------
1622 | Name      : MOS_AndroidPropWriteValue
1623 | Purpose   : write a AndroidProp User Feature Data Value
1624 | Arguments : pPath       [in]
1625 |             pUserData   [in]  user feature key write value
1626 |             ValueType   [in]  Type of Data
1627 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1628 |             If the function fails, the return value is a error code defined
1629 |             in mos_utilities.h.
1630 | Comments  :
1631 \---------------------------------------------------------------------------*/
MOS_AndroidPropWriteValue(char * pPath,PMOS_USER_FEATURE_VALUE_DATA pUserData,MOS_USER_FEATURE_VALUE_TYPE ValueType)1632 MOS_STATUS MOS_AndroidPropWriteValue(
1633     char                                *pPath,
1634     PMOS_USER_FEATURE_VALUE_DATA        pUserData,
1635     MOS_USER_FEATURE_VALUE_TYPE         ValueType)
1636 {
1637     MOS_STATUS  eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
1638     char        prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1639     int32_t     ret = 0;
1640     MOS_OS_CHK_NULL(pPath);
1641     MOS_OS_CHK_NULL(pUserData);
1642 
1643     switch(ValueType)
1644     {
1645      case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
1646         ret = snprintf(prop, sizeof(prop), "%d\n", pUserData->bData);
1647         break;
1648     case MOS_USER_FEATURE_VALUE_TYPE_INT32:
1649         ret = snprintf(prop, sizeof(prop), "%d\n", pUserData->i32Data);
1650         break;
1651     case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
1652         ret = snprintf(prop, sizeof(prop), "%u\n", pUserData->u32Data);
1653         break;
1654     case MOS_USER_FEATURE_VALUE_TYPE_INT64:
1655         ret = snprintf(prop, sizeof(prop), "%" MOSd64 "\n", pUserData->i64Data);
1656         break;
1657     case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
1658         ret = snprintf(prop, sizeof(prop), "%" MOSu64 "\n", pUserData->u64Data);
1659         break;
1660     case MOS_USER_FEATURE_VALUE_TYPE_STRING:
1661         if ((pUserData->StringData.pStringData != nullptr) && (strlen(pUserData->StringData.pStringData) != 0))
1662         {
1663             ret = snprintf(prop, sizeof(prop), "%s\n", pUserData->StringData.pStringData);
1664         }
1665         break;
1666     default:
1667         break;
1668     }
1669     if (ret > 0)
1670     {
1671         ret = property_set(pPath, prop);
1672         if (ret == 0)
1673         {
1674             eStatus = MOS_STATUS_SUCCESS;
1675         }
1676     }
1677 finish:
1678     return eStatus;
1679 }
1680 
1681 /*----------------------------------------------------------------------------
1682 | Name      : MOS_AndroidPropCreateKey
1683 | Purpose   : set default value to AndroidProp User Feature Key according to userfeature
1684 | Arguments : pUserFeature   [in]  value for ceated key
1685 |             FuncType       [in]  Type of function
1686 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1687 |             If the function fails, the return value is a error code defined
1688 |             in mos_utilities.h.
1689 | Comments  :
1690 \---------------------------------------------------------------------------*/
MOS_AndroidPropCreateKey(PMOS_USER_FEATURE_VALUE pUserFeature,LINUX_UF_FUNC_TYPE FuncType)1691 MOS_STATUS MOS_AndroidPropCreateKey(
1692     PMOS_USER_FEATURE_VALUE     pUserFeature,
1693     LINUX_UF_FUNC_TYPE          FuncType)
1694 {
1695     char                        sPath[MAX_UF_PATH];
1696     MOS_STATUS                  eStatus = MOS_STATUS_DIR_CREATE_FAILED;
1697     MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
1698     MOS_USER_FEATURE_VALUE_TYPE ValueType = MOS_USER_FEATURE_VALUE_TYPE_INVALID;
1699     char                        prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1700     int32_t                     ret;
1701 
1702     MOS_OS_CHK_NULL(pUserFeature);
1703     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
1704 
1705     // create key
1706     MOS_ZeroMemory(sPath, MAX_UF_PATH);
1707     MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, FuncType));
1708     // set the default Data and Type value according to default value and type in pUserFeature.
1709     MOS_OS_CHK_STATUS(MOS_AndroidPropWriteValue(sPath, &pUserFeature->Value, pUserFeature->ValueType));
1710 finish:
1711     return eStatus;
1712 }
1713 
1714 /*----------------------------------------------------------------------------
1715 | Name      : MOS_AndroidPropReadValue
1716 | Purpose   : read a AndroidProp User Feature Data Value
1717 | Arguments : pPath       [in]
1718 |             pUserData   [out] To store user feature key value.
1719 |             ValueType   [in]  Type of Data
1720 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1721 |             If the function fails, the return value is a error code defined
1722 |             in mos_utilities.h.
1723 | Comments  :
1724 \---------------------------------------------------------------------------*/
MOS_AndroidPropReadValue(char * pPath,PMOS_USER_FEATURE_VALUE_DATA pUserData,MOS_USER_FEATURE_VALUE_TYPE ValueType)1725 MOS_STATUS MOS_AndroidPropReadValue(
1726     char                            *pPath,
1727     PMOS_USER_FEATURE_VALUE_DATA    pUserData,
1728     MOS_USER_FEATURE_VALUE_TYPE     ValueType)
1729 {
1730     MOS_USER_FEATURE_VALUE_DATA UserData;
1731     char                        pcTmpStr[MOS_USER_CONTROL_MAX_DATA_SIZE];
1732     MOS_STATUS                  eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
1733     char                        prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1734     int32_t                     ret = 0;
1735 
1736     MOS_OS_CHK_NULL(pPath);
1737     MOS_OS_CHK_NULL(pUserData);
1738 
1739     MOS_ZeroMemory(&UserData, sizeof(UserData));
1740 
1741     if (property_get(pPath, prop, nullptr) > 0)
1742     {
1743         switch(ValueType)
1744         {
1745          case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
1746             ret = sscanf(prop, "%d\n", &pUserData->bData);
1747             break;
1748         case MOS_USER_FEATURE_VALUE_TYPE_INT32:
1749             ret = sscanf(prop, "%d\n", &pUserData->i32Data);
1750             break;
1751         case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
1752             ret = sscanf(prop, "%u\n", &pUserData->u32Data);
1753             break;
1754         case MOS_USER_FEATURE_VALUE_TYPE_INT64:
1755             ret = sscanf(prop, "%" MOSd64 "\n", &pUserData->i64Data);
1756             break;
1757         case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
1758             ret = sscanf(prop, "%" MOSu64 "\n", &pUserData->u64Data);
1759         break;
1760         case MOS_USER_FEATURE_VALUE_TYPE_STRING:
1761             if( sscanf( prop, "%s\n", pcTmpStr) > 0 )
1762             {
1763                 if (strlen(pcTmpStr) > 0)
1764                 {
1765                     MOS_SafeFreeMemory(pUserData->StringData.pStringData);
1766                     pUserData->StringData.pStringData = (char *)MOS_AllocAndZeroMemory(strlen(pcTmpStr)+1);
1767                     MOS_SecureMemcpy(pUserData->StringData.pStringData, strlen(pcTmpStr), pcTmpStr, MOS_MIN(strlen(pcTmpStr), MOS_USER_CONTROL_MAX_DATA_SIZE));
1768                     pUserData->StringData.uSize = strlen(pcTmpStr);
1769                     ret = pUserData->StringData.uSize;
1770                 }
1771             }
1772             break;
1773         default:
1774             break;
1775         }
1776     }
1777     if (ret > 0)
1778     {
1779         eStatus = MOS_STATUS_SUCCESS;
1780     }
1781 finish:
1782     return eStatus;
1783 }
1784 
1785 /*----------------------------------------------------------------------------
1786 | Name      : MOS_UserFeatureOpenKey_AndroidProp
1787 | Purpose   : Opens the specified user feature key.
1788 | Arguments : UFKey        [in]  A handle to an open user feature key.
1789 |             lpSubKey     [in]  The name of the user feature subkey to be opened.
1790 |             ulOptions    [in]  This parameter is reserved and must be zero.
1791 |             samDesired   [in]  Reserved, could be any REGSAM type value
1792 |             phkResult    [out] A pointer to a variable that receives a handle
1793 |                                to the opened key.
1794 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1795 |             If the function fails, the return value is a error code defined
1796 |             in mos_utilities.h.
1797 | Comments  :
1798 \---------------------------------------------------------------------------*/
MOS_UserFeatureOpenKey_AndroidProp(void * UFKey,const char * lpSubKey,uint32_t ulOptions,uint32_t samDesired,void ** phkResult)1799 MOS_STATUS MOS_UserFeatureOpenKey_AndroidProp(
1800     void       *UFKey,
1801     const char *lpSubKey,
1802     uint32_t   ulOptions,
1803     uint32_t   samDesired,
1804     void       **phkResult)
1805 {
1806     char                            pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1807     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1808     PMOS_USER_FEATURE_VALUE         pUserFeature = nullptr;
1809     char                            sPath[MAX_UF_PATH];
1810     LINUX_UF_FUNC_TYPE              FuncType = LINUX_UF_FUNCTYPE_INVALID;
1811     MOS_UNUSED(UFKey);
1812     MOS_UNUSED(ulOptions);
1813 
1814     MOS_OS_CHK_NULL(lpSubKey);
1815     pUserFeature = (PMOS_USER_FEATURE_VALUE)*phkResult;
1816     MOS_OS_CHK_NULL(pUserFeature);
1817     if( strcmp(lpSubKey, pUserFeature->pcWritePath) == 0 )
1818     {
1819         FuncType = LINUX_UF_FUNCTYPE_WRITE;
1820     }
1821     else if( strcmp(lpSubKey, pUserFeature->pcPath) == 0 )
1822     {
1823         FuncType = LINUX_UF_FUNCTYPE_READ;
1824     }
1825     MOS_ZeroMemory(sPath, MAX_UF_PATH);
1826     MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, FuncType));
1827     if (MOS_AndroidPropOpenKey(sPath) != MOS_STATUS_SUCCESS)
1828     {
1829         // No Sub Key return directly
1830         eStatus = MOS_STATUS_FILE_OPEN_FAILED;
1831         // KEY_WRITE
1832         if (samDesired == KEY_WRITE)
1833         {
1834             if (MOS_AndroidPropCreateKey(pUserFeature, FuncType) != MOS_STATUS_SUCCESS)
1835             {
1836                 eStatus = MOS_STATUS_DIR_CREATE_FAILED;
1837             }
1838         }
1839         else
1840         {
1841             eStatus = MOS_STATUS_FILE_OPEN_FAILED;
1842         }
1843     }
1844 finish:
1845     return eStatus;
1846 }
1847 
1848 /*----------------------------------------------------------------------------
1849 | Name      : MOS_UserFeatureGetValue_AndroidProp
1850 | Purpose   : Retrieves the type and data for the specified user feature value.
1851 | Arguments : UFKey     [in]  A handle to an open user feature key.
1852 |             lpSubKey  [in]  The name of the user feature key. This key must be a
1853 |                             subkey of the key specified by the UFKey parameter
1854 |             lpValue   [in]  The name of the user feature value.
1855 |             dwFlags   [in]  Reserved, could be any uint32_t type value
1856 |             pdwType   [out] A pointer to a variable that receives a code
1857 |                             indicating the type of data stored in the
1858 |                             specified value.
1859 |             pvData    [out] A pointer to a buffer that receives the value's
1860 |                             data.
1861 |             pcbData   [out] A pointer to a variable that specifies the size
1862 |                             of the buffer pointed to by the pvData parameter,
1863 |                             in bytes.
1864 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1865 |             If the function fails, the return value is a error code defined
1866 |             in mos_utilities.h.
1867 | Comments  :
1868 \---------------------------------------------------------------------------*/
MOS_UserFeatureGetValue_AndroidProp(void * UFKey,const char * lpSubKey,const char * lpValue,uint32_t dwFlags,uint32_t * pdwType,void * pvData,uint32_t * pcbData)1869 MOS_STATUS MOS_UserFeatureGetValue_AndroidProp(
1870     void       *UFKey,
1871     const char *lpSubKey,
1872     const char *lpValue,
1873     uint32_t   dwFlags,
1874     uint32_t   *pdwType,
1875     void       *pvData,
1876     uint32_t   *pcbData)
1877 {
1878     char                        pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1879     int32_t                     dData;
1880     int32_t                     index = 0;
1881     PMOS_USER_FEATURE_VALUE     pSettingsValue;
1882     PMOS_USER_FEATURE_VALUE     pUserFeature = nullptr;
1883     char                        sPath[MAX_UF_PATH];
1884     MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
1885     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
1886     MOS_UNUSED(lpSubKey);
1887     MOS_UNUSED(lpValue);
1888     MOS_UNUSED(dwFlags);
1889     MOS_UNUSED(pdwType);
1890 
1891     if(UFKey == nullptr)
1892     {
1893         eStatus = MOS_STATUS_INVALID_PARAMETER;
1894         goto finish;
1895     }
1896     pUserFeature = (PMOS_USER_FEATURE_VALUE)UFKey;
1897 
1898     MOS_ZeroMemory(sPath, MAX_UF_PATH);
1899     MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, LINUX_UF_FUNCTYPE_READ));
1900 
1901     // Read Type
1902     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
1903     if (MOS_AndroidPropReadValue(sPath, &UserFeatureData, pUserFeature->ValueType) == MOS_STATUS_SUCCESS)
1904     {
1905         // get key content from user feature
1906         switch(pUserFeature->ValueType)
1907         {
1908         case MOS_USER_FEATURE_VALUE_TYPE_BINARY:
1909             *(int32_t*)pvData = UserFeatureData.bData;
1910             *(uint32_t*)pcbData = sizeof(int32_t);
1911             break;
1912         case MOS_USER_FEATURE_VALUE_TYPE_INT32:
1913             *(int32_t*)pvData = UserFeatureData.i32Data;
1914             *(uint32_t*)pcbData = sizeof(int32_t);
1915             break;
1916         case MOS_USER_FEATURE_VALUE_TYPE_INT64:
1917             *(int64_t*)pvData = UserFeatureData.i64Data;
1918             *(uint32_t*)pcbData = sizeof(int64_t);
1919             break;
1920         case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
1921             *(uint32_t*)pvData = UserFeatureData.u32Data;
1922             *(uint32_t*)pcbData = sizeof(uint32_t);
1923             break;
1924         case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
1925             *(uint64_t*)pvData = UserFeatureData.u64Data;
1926             *(uint32_t*)pcbData = sizeof(uint64_t);
1927             break;
1928         case MOS_USER_FEATURE_VALUE_TYPE_STRING:
1929             MOS_SecureMemcpy(pvData, UserFeatureData.StringData.uSize, UserFeatureData.StringData.pStringData, UserFeatureData.StringData.uSize);
1930             MOS_SafeFreeMemory(UserFeatureData.StringData.pStringData);
1931             *(uint32_t*)pcbData = UserFeatureData.StringData.uSize;
1932             break;
1933         default:
1934             break;
1935         }// switch
1936     }
1937     else
1938     {
1939        eStatus = MOS_STATUS_FILE_NOT_FOUND;
1940     }
1941 finish:
1942     return eStatus;
1943 }
1944 
1945 /*----------------------------------------------------------------------------
1946 | Name      : MOS_UserFeatureSetValueEx_AndroidProp
1947 | Purpose   : Sets the data and type of a specified value under a user feature key.
1948 | Arguments : UFKey        [in] A handle to an open user feature key.
1949 |             lpValueName  [in] The name of the user feature value.
1950 |             Reserved     [in] This parameter is reserved and must be NULL.
1951 |             dwType       [in] The type of data pointed to by the lpData
1952 |                               parameter.
1953 |             lpData       [in] The data to be stored.
1954 |             cbData       [in] The size of the information pointed to by the
1955 |                               lpData parameter, in bytes.
1956 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1957 |             If the function fails, the return value is a error code defined
1958 |             in mos_utilities.h.
1959 | Comments  :
1960 \---------------------------------------------------------------------------*/
MOS_UserFeatureSetValueEx_AndroidProp(void * UFKey,const char * lpValueName,uint32_t Reserved,uint32_t dwType,uint8_t * lpData,uint32_t cbData)1961 MOS_STATUS MOS_UserFeatureSetValueEx_AndroidProp(
1962     void            *UFKey,
1963     const char      *lpValueName,
1964     uint32_t        Reserved,
1965     uint32_t        dwType,
1966     uint8_t         *lpData,
1967     uint32_t        cbData)
1968 {
1969     char                        pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1970     int32_t                     dData;
1971     int32_t                     index = 0;
1972     uint32_t                    ui;
1973     PMOS_USER_FEATURE_VALUE     pUserFeature = nullptr;
1974     char                        sPath[MAX_UF_PATH];
1975     MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
1976     MOS_USER_FEATURE_VALUE_TYPE ValueType = MOS_USER_FEATURE_VALUE_TYPE_INVALID;
1977     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
1978     MOS_UNUSED(lpValueName);
1979     MOS_UNUSED(Reserved);
1980     MOS_UNUSED(dwType);
1981 
1982     if(UFKey == nullptr)
1983     {
1984        eStatus = MOS_STATUS_INVALID_PARAMETER;
1985        goto finish;
1986     }
1987     pUserFeature = (PMOS_USER_FEATURE_VALUE)UFKey;
1988     for (ui = 0; ui < pUserFeature->uiNumOfValues; ui++)
1989     {
1990         // Check the Key exist or not
1991         MOS_ZeroMemory(sPath, MAX_UF_PATH);
1992         MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, LINUX_UF_FUNCTYPE_WRITE));
1993 
1994         if (MOS_AndroidPropOpenKey(sPath) != MOS_STATUS_SUCCESS){
1995             // create the Key according to pFeatureValue->ValueType
1996             if( MOS_AndroidPropCreateKey(pUserFeature, LINUX_UF_FUNCTYPE_WRITE) != MOS_STATUS_SUCCESS )
1997             {
1998                 eStatus = MOS_STATUS_DIR_CREATE_FAILED;
1999                 goto finish;
2000             }
2001         }
2002         MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
2003         ValueType = (MOS_USER_FEATURE_VALUE_TYPE)pUserFeature->ValueType;
2004         switch(ValueType)
2005         {
2006         case MOS_USER_FEATURE_VALUE_TYPE_BINARY:
2007             UserFeatureData.bData =*(int32_t*)lpData ;
2008             break;
2009         case MOS_USER_FEATURE_VALUE_TYPE_INT32:
2010             UserFeatureData.i32Data =*(int32_t*)lpData ;
2011             break;
2012         case MOS_USER_FEATURE_VALUE_TYPE_INT64:
2013             UserFeatureData.i64Data =*(int64_t*)lpData;
2014             break;
2015         case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
2016             UserFeatureData.u32Data = *(uint32_t*)lpData;
2017             break;
2018         case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
2019             UserFeatureData.u64Data =*(uint64_t*)lpData;
2020             break;
2021         case MOS_USER_FEATURE_VALUE_TYPE_STRING:
2022             UserFeatureData.StringData.pStringData =(char *)lpData;
2023             UserFeatureData.StringData.uSize = cbData;
2024             break;
2025         default:
2026             break;
2027         }//switch
2028         if (MOS_AndroidPropWriteValue(sPath, &UserFeatureData, ValueType) != MOS_STATUS_SUCCESS)
2029         {
2030             eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
2031             goto finish;
2032         }
2033     }
2034 finish:
2035     return eStatus;
2036 }
2037 #endif
2038 
2039 /*----------------------------------------------------------------------------
2040 | Name      : MOS_UserFeatureOpenKey_File
2041 | Purpose   : Opens the specified user feature key.
2042 | Arguments : UFKey        [in]  A handle to an open user feature key.
2043 |             lpSubKey     [in]  The name of the user feature subkey to be opened.
2044 |             ulOptions    [in]  This parameter is reserved and must be zero.
2045 |             samDesired   [in]  Reserved, could be any REGSAM type value
2046 |             phkResult    [out] A pointer to a variable that receives a handle
2047 |                                to the opened key.
2048 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
2049 |             If the function fails, the return value is a error code defined
2050 |             in mos_utilities.h.
2051 | Comments  :
2052 \---------------------------------------------------------------------------*/
MOS_UserFeatureOpenKey_File(void * UFKey,const char * lpSubKey,uint32_t ulOptions,uint32_t samDesired,void ** phkResult)2053 MOS_STATUS MOS_UserFeatureOpenKey_File(
2054     void       *UFKey,
2055     const char *lpSubKey,
2056     uint32_t   ulOptions,  // reserved
2057     uint32_t   samDesired,
2058     void       **phkResult)
2059 {
2060     char           pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2061     MOS_STATUS     iRet;
2062     uintptr_t      h_key = (uintptr_t)UFKey;
2063     MOS_UNUSED(ulOptions);
2064     MOS_UNUSED(samDesired);
2065 
2066     if((h_key == 0) /*|| (lpSubKey == nullptr)*/ || (phkResult == nullptr))    //[SH]: subkey can be NULL???
2067     {
2068         return MOS_STATUS_INVALID_PARAMETER;
2069     }
2070 
2071     MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH*sizeof(char));
2072     switch(h_key)
2073     {
2074     case UFKEY_INTERNAL:
2075         MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_INTERNAL);
2076         break;
2077     case UFKEY_EXTERNAL:
2078         MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_EXTERNAL);
2079         break;
2080     default:
2081         break;
2082     }
2083 
2084     MOS_SecureStrcat(pcKeyName, sizeof(pcKeyName), lpSubKey);
2085     iRet =  _UserFeature_GetKeyIdbyName(pcKeyName, phkResult);
2086 
2087     return iRet;
2088 }
2089 
2090 /*----------------------------------------------------------------------------
2091 | Name      : MOS_UserFeatureGetValue_File
2092 | Purpose   : Retrieves the type and data for the specified user feature value.
2093 | Arguments : UFKey     [in]  A handle to an open user feature key.
2094 |             lpSubKey  [in]  The name of the user feature key. This key must be a
2095 |                             subkey of the key specified by the UFKey parameter
2096 |             lpValue   [in]  The name of the user feature value.
2097 |             dwFlags   [in]  Reserved, could be any uint32_t type value
2098 |             pdwType   [out] A pointer to a variable that receives a code
2099 |                             indicating the type of data stored in the
2100 |                             specified value.
2101 |             pvData    [out] A pointer to a buffer that receives the value's
2102 |                             data.
2103 |             pcbData   [out] A pointer to a variable that specifies the size
2104 |                             of the buffer pointed to by the pvData parameter,
2105 |                             in bytes.
2106 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
2107 |             If the function fails, the return value is a error code defined
2108 |             in mos_utilities.h.
2109 | Comments  :
2110 \---------------------------------------------------------------------------*/
MOS_UserFeatureGetValue_File(void * UFKey,const char * lpSubKey,const char * lpValue,uint32_t dwFlags,uint32_t * pdwType,void * pvData,uint32_t * pcbData)2111 MOS_STATUS MOS_UserFeatureGetValue_File(
2112     void       *UFKey,
2113     const char *lpSubKey,
2114     const char *lpValue,
2115     uint32_t   dwFlags,
2116     uint32_t   *pdwType,
2117     void       *pvData,
2118     uint32_t   *pcbData)
2119 {
2120     char          pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2121     MOS_STATUS    eStatus;
2122     MOS_UNUSED(dwFlags);
2123 
2124     if(UFKey == nullptr)
2125     {
2126         return MOS_STATUS_INVALID_PARAMETER;
2127     }
2128 
2129     eStatus = MOS_STATUS_UNKNOWN;
2130     MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH * sizeof(char));
2131     if ( (eStatus = _UserFeature_GetKeyNamebyId(UFKey,pcKeyName)) != MOS_STATUS_SUCCESS)
2132     {
2133         return eStatus;
2134     }
2135 
2136     if(lpSubKey != nullptr)
2137     {
2138         MOS_SecureStrcat(pcKeyName, sizeof(pcKeyName), lpSubKey);
2139     }
2140     eStatus = _UserFeature_QueryValue(pcKeyName,
2141                                   lpValue,
2142                                   (uint32_t*)pdwType,
2143                                   pvData,
2144                                   (int32_t*)pcbData);
2145 
2146     return eStatus;
2147 }
2148 
2149 /*----------------------------------------------------------------------------
2150 | Name      : MOS_UserFeatureSetValueEx_File
2151 | Purpose   : Sets the data and type of a specified value under a user feature key.
2152 | Arguments : UFKey        [in] A handle to an open user feature key.
2153 |             lpValueName  [in] The name of the user feature value.
2154 |             Reserved      in] This parameter is reserved and must be NULL.
2155 |             dwType       [in] The type of data pointed to by the lpData
2156 |                               parameter.
2157 |             lpData       [in] The data to be stored.
2158 |             cbData       [in] The size of the information pointed to by the
2159 |                               lpData parameter, in bytes.
2160 | Returns   : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
2161 |             If the function fails, the return value is a error code defined
2162 |             in mos_utilities.h.
2163 | Comments  :
2164 \---------------------------------------------------------------------------*/
MOS_UserFeatureSetValueEx_File(void * UFKey,const char * lpValueName,uint32_t Reserved,uint32_t dwType,uint8_t * lpData,uint32_t cbData)2165 MOS_STATUS MOS_UserFeatureSetValueEx_File(
2166     void            *UFKey,
2167     const char      *lpValueName,
2168     uint32_t        Reserved,
2169     uint32_t        dwType,
2170     uint8_t         *lpData,
2171     uint32_t        cbData)
2172 {
2173     char    pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2174     MOS_STATUS  eStatus;
2175     MOS_UNUSED(Reserved);
2176 
2177     if (UFKey == nullptr)
2178     {
2179         return MOS_STATUS_INVALID_PARAMETER;
2180     }
2181     MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH*sizeof(char));
2182     if ((eStatus = _UserFeature_GetKeyNamebyId(UFKey,pcKeyName)) != MOS_STATUS_SUCCESS)
2183     {
2184         return eStatus;
2185     }
2186 
2187     eStatus = _UserFeature_SetValue(pcKeyName,lpValueName,dwType,lpData,cbData);
2188 
2189     return eStatus;
2190 }
2191 
MOS_OS_Utilities_Init(PMOS_USER_FEATURE_KEY_PATH_INFO userFeatureKeyPathInfo)2192 MOS_STATUS MOS_OS_Utilities_Init(PMOS_USER_FEATURE_KEY_PATH_INFO userFeatureKeyPathInfo)
2193 {
2194     MOS_STATUS     eStatus = MOS_STATUS_SUCCESS;
2195     MOS_UNUSED(userFeatureKeyPathInfo);
2196 
2197     // lock mutex to avoid multi init in multi-threading env
2198     MOS_LockMutex(&gMosUtilMutex);
2199 
2200 #if (_DEBUG || _RELEASE_INTERNAL)
2201     // Get use user feature file from env, instead of default.
2202     FILE* fp = nullptr;
2203     static char* tmpFile = getenv("GFX_FEATURE_FILE");
2204 
2205     if (tmpFile != nullptr)
2206     {
2207       if ((fp = fopen(tmpFile, "r")) != nullptr)
2208       {
2209         szUserFeatureFile = tmpFile;
2210         fclose(fp);
2211         MOS_OS_NORMALMESSAGE("using %s for USER_FEATURE_FILE", szUserFeatureFile);
2212       }
2213       else
2214       {
2215         MOS_OS_ASSERTMESSAGE("Can't open %s for USER_FEATURE_FILE!!!", tmpFile);
2216         eStatus =  MOS_STATUS_FILE_NOT_FOUND;
2217         goto finish;
2218       }
2219     }
2220 #endif
2221 
2222     if (uiMOSUtilInitCount == 0)
2223     {
2224         pUFKeyOps = (PUFKEYOPS)MOS_AllocAndZeroMemory(sizeof(UFKEYOPS));
2225         MOS_OS_CHK_NULL(pUFKeyOps);
2226 #ifdef ANDROID
2227         if (MOS_InitAndroidPropInfo() == MOS_STATUS_SUCCESS)
2228         {
2229             pUFKeyOps->pfnUserFeatureOpenKey = MOS_UserFeatureOpenKey_AndroidProp;
2230             pUFKeyOps->pfnUserFeatureGetValue = MOS_UserFeatureGetValue_AndroidProp;
2231             pUFKeyOps->pfnUserFeatureSetValueEx = MOS_UserFeatureSetValueEx_AndroidProp;
2232         }
2233         else
2234 #endif
2235         {
2236             pUFKeyOps->pfnUserFeatureOpenKey = MOS_UserFeatureOpenKey_File;
2237             pUFKeyOps->pfnUserFeatureGetValue = MOS_UserFeatureGetValue_File;
2238             pUFKeyOps->pfnUserFeatureSetValueEx = MOS_UserFeatureSetValueEx_File;
2239         }
2240         //Init MOS User Feature Key from mos desc table
2241         eStatus = MOS_DeclareUserFeatureKeysForAllDescFields();
2242 
2243 #if _MEDIA_RESERVED
2244         codecUserFeatureExt = new CodechalUserSettingsMgr();
2245         vpUserFeatureExt    = new VphalUserSettingsMgr();
2246 #endif // _MEDIA_RESERVED
2247         eStatus = MOS_GenerateUserFeatureKeyXML();
2248 #if MOS_MESSAGES_ENABLED
2249         // Initialize MOS message params structure and HLT
2250         MOS_MessageInit();
2251 #endif // MOS_MESSAGES_ENABLED
2252         MosMemAllocCounter     = 0;
2253         MosMemAllocFakeCounter = 0;
2254         MosMemAllocCounterGfx  = 0;
2255         MOS_TraceEventInit();
2256     }
2257     uiMOSUtilInitCount++;
2258 
2259 finish:
2260     MOS_UnlockMutex(&gMosUtilMutex);
2261     return eStatus;
2262 }
2263 
MOS_OS_Utilities_Close()2264 MOS_STATUS MOS_OS_Utilities_Close()
2265 {
2266     int32_t                             MemoryCounter = 0;
2267     MOS_USER_FEATURE_VALUE_WRITE_DATA   UserFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__;
2268     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
2269 
2270     // lock mutex to avoid multi close in multi-threading env
2271     MOS_LockMutex(&gMosUtilMutex);
2272     uiMOSUtilInitCount--;
2273     if (uiMOSUtilInitCount == 0 )
2274     {
2275         MOS_TraceEventClose();
2276         MosMemAllocCounter -= MosMemAllocFakeCounter;
2277         MemoryCounter = MosMemAllocCounter + MosMemAllocCounterGfx;
2278         MosMemAllocCounterNoUserFeature = MosMemAllocCounter;
2279         MosMemAllocCounterNoUserFeatureGfx = MosMemAllocCounterGfx;
2280         MOS_OS_VERBOSEMESSAGE("MemNinja leak detection end");
2281 
2282         UserFeatureWriteData.Value.i32Data    =   MemoryCounter;
2283         UserFeatureWriteData.ValueID          = __MEDIA_USER_FEATURE_VALUE_MEMNINJA_COUNTER_ID;
2284         MOS_UserFeature_WriteValues_ID(NULL, &UserFeatureWriteData, 1);
2285 
2286         eStatus = MOS_DestroyUserFeatureKeysForAllDescFields();
2287 #if _MEDIA_RESERVED
2288         if (codecUserFeatureExt)
2289         {
2290             delete codecUserFeatureExt;
2291             codecUserFeatureExt = nullptr;
2292         }
2293         if (vpUserFeatureExt)
2294         {
2295             delete vpUserFeatureExt;
2296             vpUserFeatureExt = nullptr;
2297         }
2298 #endif // _MEDIA_RESERVED
2299 #if (_DEBUG || _RELEASE_INTERNAL)
2300         // MOS maintains a reference counter,
2301         // so if there still is another active lib instance, logs would still be printed.
2302         MOS_MessageClose();
2303 #endif
2304         MOS_FreeMemory(pUFKeyOps);
2305         pUFKeyOps = nullptr;
2306     }
2307     MOS_UnlockMutex(&gMosUtilMutex);
2308     return eStatus;
2309 }
2310 
MOS_UserFeatureOpenKey(void * UFKey,const char * lpSubKey,uint32_t ulOptions,uint32_t samDesired,void ** phkResult)2311 MOS_STATUS MOS_UserFeatureOpenKey(
2312     void       *UFKey,
2313     const char *lpSubKey,
2314     uint32_t   ulOptions,
2315     uint32_t   samDesired,
2316     void       **phkResult)
2317 {
2318     char           pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2319     MOS_STATUS     iRet;
2320     intptr_t       h_key = (intptr_t)UFKey;
2321 
2322     if((h_key == 0) /*|| (lpSubKey == nullptr)*/ || (phkResult == nullptr))    //[SH]: subkey can be NULL???
2323     {
2324         return MOS_STATUS_INVALID_PARAMETER;
2325     }
2326     if (( pUFKeyOps != nullptr) && (pUFKeyOps->pfnUserFeatureOpenKey != nullptr))
2327     {
2328         return pUFKeyOps->pfnUserFeatureOpenKey(UFKey, lpSubKey, ulOptions, samDesired, phkResult);
2329     }
2330     else
2331     {
2332         return MOS_UserFeatureOpenKey_File(UFKey, lpSubKey, ulOptions, samDesired, phkResult);
2333     }
2334 }
2335 
MOS_UserFeatureCloseKey(void * UFKey)2336 MOS_STATUS MOS_UserFeatureCloseKey(void  *UFKey)
2337 {
2338     MOS_UNUSED(UFKey);
2339     //always return success, because we actually dong't have a key opened.
2340     return MOS_STATUS_SUCCESS;
2341 }
2342 
MOS_UserFeatureGetValue(void * UFKey,const char * lpSubKey,const char * lpValue,uint32_t dwFlags,uint32_t * pdwType,void * pvData,uint32_t * pcbData)2343 MOS_STATUS MOS_UserFeatureGetValue(
2344     void       *UFKey,
2345     const char *lpSubKey,
2346     const char *lpValue,
2347     uint32_t   dwFlags,
2348     uint32_t   *pdwType,
2349     void       *pvData,
2350     uint32_t   *pcbData)
2351 {
2352     char          pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2353     MOS_STATUS    eStatus;
2354 
2355     if(UFKey == nullptr)
2356     {
2357         return MOS_STATUS_INVALID_PARAMETER;
2358     }
2359 
2360     eStatus = MOS_STATUS_UNKNOWN;
2361     if (( pUFKeyOps != nullptr) && (pUFKeyOps->pfnUserFeatureGetValue != nullptr))
2362     {
2363         return pUFKeyOps->pfnUserFeatureGetValue(UFKey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
2364     }
2365     else
2366     {
2367         return MOS_UserFeatureGetValue_File(UFKey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
2368     }
2369 
2370 }
2371 
MOS_UserFeatureQueryValueEx(void * UFKey,char * lpValueName,uint32_t * lpReserved,uint32_t * lpType,char * lpData,uint32_t * lpcbData)2372 MOS_STATUS MOS_UserFeatureQueryValueEx(
2373     void            *UFKey,
2374     char            *lpValueName,
2375     uint32_t        *lpReserved,
2376     uint32_t        *lpType,
2377     char            *lpData,
2378     uint32_t        *lpcbData)
2379 {
2380     MOS_UNUSED(lpReserved);
2381     return MOS_UserFeatureGetValue(UFKey, "", lpValueName, 0, lpType, lpData, lpcbData);
2382 }
2383 
MOS_UserFeatureSetValueEx(void * UFKey,const char * lpValueName,uint32_t Reserved,uint32_t dwType,uint8_t * lpData,uint32_t cbData)2384 MOS_STATUS MOS_UserFeatureSetValueEx(
2385     void            *UFKey,
2386     const char      *lpValueName,
2387     uint32_t        Reserved,
2388     uint32_t        dwType,
2389     uint8_t         *lpData,
2390     uint32_t        cbData)
2391 {
2392     char        pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2393     MOS_STATUS  eStatus;
2394 
2395     if (UFKey == nullptr)
2396     {
2397         return MOS_STATUS_INVALID_PARAMETER;
2398     }
2399     if (( pUFKeyOps != nullptr) && (pUFKeyOps->pfnUserFeatureSetValueEx!= nullptr))
2400     {
2401         return pUFKeyOps->pfnUserFeatureSetValueEx(UFKey, lpValueName, Reserved, dwType, lpData, cbData);
2402     }
2403     else
2404     {
2405         return MOS_UserFeatureSetValueEx_File(UFKey, lpValueName, Reserved, dwType, lpData, cbData);
2406     }
2407 }
2408 
2409 // Event Related Functions: Android does not support these
2410 #ifndef ANDROID
MOS_UserFeatureNotifyChangeKeyValue(void * UFKey,int32_t bWatchSubtree,HANDLE hEvent,int32_t fAsynchronous)2411 MOS_STATUS MOS_UserFeatureNotifyChangeKeyValue(
2412     void                *UFKey,
2413     int32_t             bWatchSubtree,
2414     HANDLE              hEvent,
2415     int32_t             fAsynchronous)
2416 {
2417     key_t          key;
2418     int32_t        semid;
2419     struct sembuf  operation[1] ;
2420 
2421     key = ftok(szUserFeatureFile,1);
2422     semid = semget(key,1,0);
2423     //change semaphore
2424     operation[0].sem_op  = 1;
2425     operation[0].sem_num = 0;
2426     operation[0].sem_flg = SEM_UNDO;
2427     semop(semid, operation, 1);
2428 
2429     return MOS_STATUS_SUCCESS;
2430 }
2431 
MOS_CreateEventEx(void * lpEventAttributes,char * lpName,uint32_t dwFlags)2432 HANDLE MOS_CreateEventEx(
2433     void                *lpEventAttributes,
2434     char                *lpName,
2435     uint32_t            dwFlags)
2436 {
2437     int32_t     semid;
2438     key_t       key;
2439     union semun
2440     {
2441         int32_t val;
2442         struct semid_ds *Buf;
2443         unsigned short *array;
2444     } semctl_arg;
2445 
2446     semid = 0;
2447 
2448     //Generate a unique key, U can also supply a value instead
2449     key = ftok(szUserFeatureFile, 1);
2450     semid = semget(key,  1, 0666 | IPC_CREAT );
2451     semctl_arg.val = 0; //Setting semval to 0
2452     semctl(semid, 0, SETVAL, semctl_arg);
2453 
2454     HANDLE ret = reinterpret_cast<HANDLE>(semid);
2455 
2456     return ret;
2457 }
2458 
MOS_UserFeatureWaitForSingleObject(PTP_WAIT * phNewWaitObject,HANDLE hObject,void * Callback,void * Context)2459 int32_t MOS_UserFeatureWaitForSingleObject(
2460     PTP_WAIT*           phNewWaitObject,
2461     HANDLE              hObject,
2462     void                *Callback,
2463     void                *Context)
2464 {
2465     int32_t                  iRet;
2466     int32_t                  semid;
2467     struct sembuf            operation[1];
2468     pid_t                    pid;
2469     MOS_UserFeatureCallback  pCallback;
2470     LARGE_INTEGER            largeInteger;
2471 
2472     pCallback = (MOS_UserFeatureCallback)Callback;
2473 
2474     iRet  = 0;
2475 
2476     largeInteger.QuadPart = (int64_t)hObject;
2477 
2478     semid = largeInteger.u.LowPart;
2479 
2480     if ((pid=fork()) == -1)
2481     {
2482         printf("error\n");
2483     }
2484     else if(pid == 0)
2485     {
2486         while(1)
2487         {
2488             operation[0].sem_op = -1;
2489             operation[0].sem_num = 0;
2490             //now waiting
2491             semop(semid, operation, 1);
2492             pCallback(Context, 0);
2493         }
2494         exit(0);
2495     }
2496     else
2497     {
2498         iRet = pid;
2499     }
2500 
2501     *phNewWaitObject = reinterpret_cast<PTP_WAIT>(iRet);
2502 
2503     return (iRet != 0);
2504 }
2505 
MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle)2506 int32_t MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle)
2507 {
2508     int32_t iPid;
2509     LARGE_INTEGER largeInteger;
2510 
2511     largeInteger.QuadPart = (int64_t)hWaitHandle;
2512 
2513     iPid = largeInteger.u.LowPart;
2514     kill(iPid,SIGKILL);
2515     return true;
2516 }
2517 
2518 /*----------------------------------------------------------------------------
2519 | Name      : GMMDebugBreak
2520 | Purpose   : Fix compiling issue for Gmmlib on debug mode
2521 | Arguments : N/A
2522 | Returns   : void
2523 | Calls     : N/A
2524 | Callers   : Several
2525 \---------------------------------------------------------------------------*/
GMMDebugBreak(const char * file,const char * function,const int32_t line)2526 void GMMDebugBreak(const char  *file, const char  *function,const int32_t line)
2527 {
2528     // Not required for media driver
2529     return;
2530 }
2531 
2532 /*----------------------------------------------------------------------------
2533 | Name      : GMMPrintMessage
2534 | Purpose   : Fix compiling issue for Gmmlib on debug mode
2535 | Arguments : N/A
2536 | Returns   : void
2537 | Calls     : N/A
2538 | Callers   : Several
2539 \---------------------------------------------------------------------------*/
GMMPrintMessage(int32_t debuglevel,const char * function,...)2540 void GMMPrintMessage(int32_t debuglevel, const char  *function, ...)
2541 {
2542     // Not Required for media driver
2543     return;
2544 }
2545 
2546 #else // ANDROID
MOS_UserFeatureNotifyChangeKeyValue(void * UFKey,int32_t bWatchSubtree,HANDLE hEvent,int32_t fAsynchronous)2547 MOS_STATUS MOS_UserFeatureNotifyChangeKeyValue(
2548     void                *UFKey,
2549     int32_t             bWatchSubtree,
2550     HANDLE              hEvent,
2551     int32_t             fAsynchronous)
2552 {
2553     MOS_UNUSED(UFKey);
2554     MOS_UNUSED(bWatchSubtree);
2555     MOS_UNUSED(hEvent);
2556     MOS_UNUSED(fAsynchronous);
2557     return MOS_STATUS_SUCCESS;
2558 }
2559 
MOS_CreateEventEx(void * lpEventAttributes,char * lpName,uint32_t dwFlags)2560 HANDLE MOS_CreateEventEx(
2561     void                *lpEventAttributes,
2562     char                *lpName,
2563     uint32_t            dwFlags)
2564 {
2565     MOS_UNUSED(lpEventAttributes);
2566     MOS_UNUSED(lpName);
2567     MOS_UNUSED(dwFlags);
2568     return (HANDLE)1;
2569 }
2570 
MOS_UserFeatureWaitForSingleObject(PTP_WAIT * phNewWaitObject,HANDLE hObject,void * Callback,void * Context)2571 int32_t MOS_UserFeatureWaitForSingleObject(
2572     PTP_WAIT*           phNewWaitObject,
2573     HANDLE              hObject,
2574     void                *Callback,
2575     void                *Context)
2576 {
2577     MOS_UNUSED(phNewWaitObject);
2578     MOS_UNUSED(hObject);
2579     MOS_UNUSED(Callback);
2580     MOS_UNUSED(Context);
2581     return true;
2582 }
2583 
MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle)2584 int32_t MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle)
2585 {
2586     MOS_UNUSED(hWaitHandle);
2587     return true;
2588 }
2589 #endif // !ANDROID
2590 
MOS_UserFeature_ParsePath(PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,char * const pInputPath,PMOS_USER_FEATURE_TYPE pUserFeatureType,char ** ppSubPath)2591 MOS_STATUS MOS_UserFeature_ParsePath(
2592     PMOS_USER_FEATURE_INTERFACE     pOsUserFeatureInterface,
2593     char * const                    pInputPath,
2594     PMOS_USER_FEATURE_TYPE          pUserFeatureType,
2595     char                            **ppSubPath)
2596 {
2597     char                            *pValue;
2598     MOS_USER_FEATURE_TYPE           UserFeatureType;
2599     size_t                          uUFKeyLen;
2600     size_t                          uHKeyLen;
2601     size_t                          uValLen;
2602     size_t                          uSepLen;
2603     MOS_UNUSED(pOsUserFeatureInterface);
2604 
2605     //-------------------------------------------
2606     // the UserFeature interface is not currently an actual interface, just a collection
2607     // of functions, so pOsUserFeatureInterface will always be nullptr until this changes
2608     //MOS_OS_ASSERT(pOsUserFeatureInterface);
2609     MOS_OS_ASSERT(pInputPath);
2610     MOS_OS_ASSERT(strlen(pInputPath) > 0);
2611     MOS_OS_ASSERT(pUserFeatureType);
2612     MOS_OS_ASSERT(ppSubPath);
2613     //-------------------------------------------
2614 
2615     pValue = nullptr;
2616 
2617     pValue = strstr(pInputPath, MOS_UF_SEPARATOR);
2618 
2619     if (!pValue)
2620     {
2621         MOS_OS_ASSERTMESSAGE("Invalid user feature key %s.", pInputPath);
2622         return MOS_STATUS_INVALID_PARAMETER;
2623     }
2624 
2625     uUFKeyLen   = strlen(pInputPath);
2626     uValLen     = strlen(pValue);
2627     uSepLen     = strlen(MOS_UF_SEPARATOR);
2628     uHKeyLen    = uUFKeyLen - uValLen;
2629 
2630     if (uHKeyLen == 0)
2631     {
2632         MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. Path separator in the begining.", pInputPath);
2633         return MOS_STATUS_INVALID_PARAMETER;
2634     }
2635 
2636     if (uValLen <= uSepLen)
2637     {
2638         MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. No value after path separator.", pInputPath);
2639         return MOS_STATUS_INVALID_PARAMETER;
2640     }
2641 
2642     if ((uHKeyLen == strlen(MOS_UFKEY_EXT)) &&
2643         (strncmp(pInputPath, MOS_UFKEY_EXT, uHKeyLen) == 0))
2644     {
2645         UserFeatureType = MOS_USER_FEATURE_TYPE_SYSTEM;
2646     }
2647     else if ((uHKeyLen == strlen(MOS_UFKEY_INT)) &&
2648         (strncmp(pInputPath, MOS_UFKEY_INT, uHKeyLen) == 0))
2649     {
2650         UserFeatureType = MOS_USER_FEATURE_TYPE_USER;
2651     }
2652     else
2653     {
2654         MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. Expected %s or %s.", pInputPath, MOS_UFKEY_EXT, MOS_UFKEY_INT);
2655         return MOS_STATUS_INVALID_PARAMETER;
2656     }
2657 
2658     pValue             = pValue + uSepLen;
2659 
2660     *pUserFeatureType  = UserFeatureType;
2661     *ppSubPath         = pValue;
2662 
2663     return MOS_STATUS_SUCCESS;
2664 }
2665 
MOS_GetLogicalCoreNumber()2666 uint32_t MOS_GetLogicalCoreNumber()
2667 {
2668     return sysconf(_SC_NPROCESSORS_CONF);
2669 }
2670 
MOS_CreateThread(void * ThreadFunction,void * ThreadData)2671 MOS_THREADHANDLE MOS_CreateThread(
2672     void                        *ThreadFunction,
2673     void                        *ThreadData)
2674 {
2675     MOS_THREADHANDLE Thread;
2676 
2677     if (0 != pthread_create(&Thread, nullptr, (void *(*)(void *))ThreadFunction, ThreadData))
2678     {
2679         Thread = 0;
2680         MOS_OS_ASSERTMESSAGE("Create thread failed.");
2681     }
2682 
2683     return Thread;
2684 }
2685 
MOS_GetThreadId(MOS_THREADHANDLE hThread)2686 uint32_t MOS_GetThreadId(
2687     MOS_THREADHANDLE            hThread)
2688 {
2689     MOS_UNUSED(hThread);
2690     return 0;
2691 }
2692 
MOS_GetCurrentThreadId()2693 uint32_t MOS_GetCurrentThreadId()
2694 {
2695     return (uint32_t)pthread_self();
2696 }
2697 
MOS_WaitThread(MOS_THREADHANDLE hThread)2698 MOS_STATUS MOS_WaitThread(
2699     MOS_THREADHANDLE            hThread)
2700 {
2701     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
2702 
2703     if (hThread == 0)
2704     {
2705         MOS_OS_ASSERTMESSAGE("MOS wait thread failed, invalid thread handle.");
2706         eStatus = MOS_STATUS_INVALID_PARAMETER;
2707     }
2708     else if (0 != pthread_join(hThread, nullptr))
2709     {
2710         MOS_OS_ASSERTMESSAGE("Failed to join thread.");
2711         eStatus = MOS_STATUS_UNKNOWN;
2712     }
2713 
2714     return eStatus;
2715 }
2716 
MOS_CreateMutex()2717 PMOS_MUTEX MOS_CreateMutex()
2718 {
2719     PMOS_MUTEX pMutex;
2720 
2721     pMutex = (PMOS_MUTEX)MOS_AllocMemory(sizeof(*pMutex));
2722     if (pMutex != nullptr)
2723     {
2724         if (pthread_mutex_init(pMutex, nullptr))
2725         {
2726             MOS_FreeMemory(pMutex);
2727             pMutex = nullptr;
2728         }
2729     }
2730 
2731     return pMutex;
2732 }
2733 
MOS_DestroyMutex(PMOS_MUTEX pMutex)2734 MOS_STATUS MOS_DestroyMutex(PMOS_MUTEX pMutex)
2735 {
2736     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2737 
2738     if (pMutex)
2739     {
2740         if (pthread_mutex_destroy(pMutex))
2741         {
2742             eStatus = MOS_STATUS_UNKNOWN;
2743         }
2744         MOS_FreeMemory(pMutex);
2745     }
2746 
2747     return eStatus;
2748 }
2749 
MOS_LockMutex(PMOS_MUTEX pMutex)2750 MOS_STATUS MOS_LockMutex(PMOS_MUTEX pMutex)
2751 {
2752     MOS_OS_CHK_NULL_RETURN(pMutex);
2753 
2754     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2755 
2756     if (pthread_mutex_lock(pMutex))
2757     {
2758         eStatus = MOS_STATUS_UNKNOWN;
2759     }
2760 
2761     return eStatus;
2762 }
2763 
MOS_UnlockMutex(PMOS_MUTEX pMutex)2764 MOS_STATUS MOS_UnlockMutex(PMOS_MUTEX pMutex)
2765 {
2766     MOS_OS_CHK_NULL_RETURN(pMutex);
2767 
2768     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2769 
2770     if (pthread_mutex_unlock(pMutex))
2771     {
2772         eStatus = MOS_STATUS_UNKNOWN;
2773     }
2774 
2775     return eStatus;
2776 }
2777 
MOS_CreateSemaphore(uint32_t uiInitialCount,uint32_t uiMaximumCount)2778 PMOS_SEMAPHORE MOS_CreateSemaphore(
2779     uint32_t            uiInitialCount,
2780     uint32_t            uiMaximumCount)
2781 {
2782     PMOS_SEMAPHORE pSemaphore = nullptr;
2783     MOS_UNUSED(uiMaximumCount);
2784 
2785     pSemaphore = (PMOS_SEMAPHORE)MOS_AllocMemory(sizeof(*pSemaphore));
2786     if (!pSemaphore)
2787         return nullptr;
2788     if (sem_init(pSemaphore, 0, uiInitialCount))
2789     {
2790         MOS_SafeFreeMemory(pSemaphore);
2791         pSemaphore = nullptr;
2792     }
2793 
2794     return pSemaphore;
2795 }
2796 
MOS_DestroySemaphore(PMOS_SEMAPHORE pSemaphore)2797 MOS_STATUS MOS_DestroySemaphore(
2798     PMOS_SEMAPHORE              pSemaphore)
2799 {
2800     MOS_SafeFreeMemory(pSemaphore);
2801 
2802     return MOS_STATUS_SUCCESS;
2803 }
2804 
MOS_WaitSemaphore(PMOS_SEMAPHORE pSemaphore,uint32_t uiMilliseconds)2805 MOS_STATUS MOS_WaitSemaphore(
2806     PMOS_SEMAPHORE              pSemaphore,
2807     uint32_t                    uiMilliseconds)
2808 {
2809     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
2810 
2811     if (uiMilliseconds == INFINITE)
2812     {
2813         if (sem_wait(pSemaphore))
2814         {
2815             eStatus = MOS_STATUS_UNKNOWN;
2816         }
2817     }
2818     else
2819     {
2820         struct timespec time = {
2821             (int32_t)uiMilliseconds / 1000000,
2822             ((int32_t)uiMilliseconds % 1000000) * 1000};
2823 
2824         if (sem_timedwait(pSemaphore, &time))
2825         {
2826             eStatus = MOS_STATUS_UNKNOWN;
2827         }
2828     }
2829 
2830     return eStatus;
2831 }
2832 
MOS_PostSemaphore(PMOS_SEMAPHORE pSemaphore,uint32_t uiPostCount)2833 MOS_STATUS MOS_PostSemaphore(
2834     PMOS_SEMAPHORE              pSemaphore,
2835     uint32_t                    uiPostCount)
2836 {
2837     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
2838 
2839     if (uiPostCount > 0)
2840     {
2841         while (uiPostCount--)
2842         {
2843             if (sem_post(pSemaphore))
2844             {
2845                 eStatus = MOS_STATUS_UNKNOWN;
2846                 break;
2847             }
2848         }
2849     }
2850     else
2851     {
2852         eStatus = MOS_STATUS_UNKNOWN;
2853     }
2854 
2855     return eStatus;
2856 }
2857 
MOS_WaitForSingleObject(void * pObject,uint32_t uiMilliseconds)2858 uint32_t MOS_WaitForSingleObject(
2859     void                        *pObject,
2860     uint32_t                    uiMilliseconds)
2861 {
2862     uint32_t WaitSignal = 0;
2863     MOS_UNUSED(pObject);
2864     MOS_UNUSED(uiMilliseconds);
2865 
2866     return WaitSignal;
2867 }
2868 
MOS_WaitForMultipleObjects(uint32_t uiThreadCount,void ** ppObjects,uint32_t bWaitAll,uint32_t uiMilliseconds)2869 uint32_t MOS_WaitForMultipleObjects(
2870     uint32_t                    uiThreadCount,
2871     void                        **ppObjects,
2872     uint32_t                    bWaitAll,
2873     uint32_t                    uiMilliseconds)
2874 {
2875     MOS_UNUSED(uiThreadCount);
2876     MOS_UNUSED(ppObjects);
2877     MOS_UNUSED(bWaitAll);
2878     MOS_UNUSED(uiMilliseconds);
2879     return 0;
2880 }
2881 
MOS_AtomicIncrement(int32_t * pValue)2882 int32_t MOS_AtomicIncrement(
2883     int32_t *pValue)
2884 {
2885     return __sync_fetch_and_add(pValue, 1);
2886 }
2887 
MOS_AtomicDecrement(int32_t * pValue)2888 int32_t MOS_AtomicDecrement(
2889     int32_t *pValue)
2890 {
2891     return __sync_fetch_and_sub(pValue, 1);
2892 }
2893 
MOS_StatusToOsResult(MOS_STATUS eStatus)2894 VAStatus MOS_StatusToOsResult(
2895     MOS_STATUS               eStatus)
2896 {
2897     switch (eStatus)
2898     {
2899         case MOS_STATUS_SUCCESS:                        return VA_STATUS_SUCCESS;
2900         case MOS_STATUS_NO_SPACE:                       return VA_STATUS_ERROR_ALLOCATION_FAILED;
2901         case MOS_STATUS_INVALID_PARAMETER:              return VA_STATUS_ERROR_INVALID_PARAMETER;
2902         case MOS_STATUS_INVALID_HANDLE:                 return VA_STATUS_ERROR_INVALID_BUFFER;
2903         case MOS_STATUS_NULL_POINTER:                   return VA_STATUS_ERROR_INVALID_CONTEXT;
2904         default:                                        return VA_STATUS_ERROR_OPERATION_FAILED;
2905     }
2906 
2907     return VA_STATUS_ERROR_OPERATION_FAILED;
2908 }
2909 
OsResultToMOS_Status(VAStatus eResult)2910 MOS_STATUS OsResultToMOS_Status(
2911     VAStatus                 eResult)
2912 {
2913     switch (eResult)
2914     {
2915         case VA_STATUS_SUCCESS:                     return MOS_STATUS_SUCCESS;
2916         case VA_STATUS_ERROR_ALLOCATION_FAILED:     return MOS_STATUS_NO_SPACE;
2917         case VA_STATUS_ERROR_INVALID_PARAMETER:     return MOS_STATUS_INVALID_PARAMETER;
2918         case VA_STATUS_ERROR_INVALID_BUFFER:        return MOS_STATUS_INVALID_HANDLE;
2919         case VA_STATUS_ERROR_INVALID_CONTEXT:       return MOS_STATUS_NULL_POINTER;
2920         default:                                    return MOS_STATUS_UNKNOWN;
2921     }
2922 
2923     return MOS_STATUS_UNKNOWN;
2924 }
2925 
MOS_GetLocalTime(struct tm * Tm)2926 MOS_STATUS MOS_GetLocalTime(
2927     struct tm* Tm)
2928 {
2929     MOS_STATUS     eStatus = MOS_STATUS_SUCCESS;
2930     struct tm      *pTm;
2931     time_t         lTime = time(nullptr);
2932     pTm = localtime(&lTime);
2933     if(pTm == nullptr)
2934     {
2935         MOS_OS_ASSERTMESSAGE("Failed to get localtime.");
2936         eStatus = MOS_STATUS_UNKNOWN;
2937         return eStatus;
2938     }
2939 
2940     eStatus = MOS_SecureMemcpy(Tm, sizeof(struct tm), pTm, sizeof(struct tm));
2941     return eStatus;
2942 }
2943 
MOS_TraceEventInit()2944 void MOS_TraceEventInit()
2945 {
2946     if (g_apoMosEnabled)
2947     {
2948         return MosUtilities::MosTraceEventInit();
2949     }
2950     // close first, if already opened.
2951     if (MosTraceFd >= 0)
2952     {
2953         close(MosTraceFd);
2954         MosTraceFd = -1;
2955     }
2956     MosTraceFd = open(MosTracePath, O_WRONLY);
2957     return;
2958 }
2959 
MOS_TraceEventClose()2960 void MOS_TraceEventClose()
2961 {
2962     if (g_apoMosEnabled)
2963     {
2964         return MosUtilities::MosTraceEventClose();
2965     }
2966     if (MosTraceFd >= 0)
2967     {
2968         close(MosTraceFd);
2969         MosTraceFd = -1;
2970     }
2971     return;
2972 }
2973 
MOS_TraceSetupInfo(uint32_t DrvVer,uint32_t PlatFamily,uint32_t RenderFamily,uint32_t DeviceID)2974 void MOS_TraceSetupInfo(uint32_t DrvVer, uint32_t PlatFamily, uint32_t RenderFamily, uint32_t DeviceID)
2975 {
2976     // not implemented
2977 }
2978 
2979 #define TRACE_EVENT_MAX_SIZE    4096
MOS_TraceEvent(uint16_t usId,uint8_t ucType,void * const pArg1,uint32_t dwSize1,void * const pArg2,uint32_t dwSize2)2980 void MOS_TraceEvent(
2981     uint16_t         usId,
2982     uint8_t          ucType,
2983     void * const     pArg1,
2984     uint32_t         dwSize1,
2985     void * const     pArg2,
2986     uint32_t         dwSize2)
2987 {
2988     if (g_apoMosEnabled)
2989     {
2990         return MosUtilities::MosTraceEvent(usId, ucType, pArg1, dwSize1, pArg2, dwSize2);
2991     }
2992 
2993     if (MosTraceFd >= 0)
2994     {
2995         char  *pTraceBuf = (char *)MOS_AllocAndZeroMemory(TRACE_EVENT_MAX_SIZE);
2996         uint32_t   nLen = 0;
2997 
2998         if (pTraceBuf)
2999         {
3000             MOS_SecureStringPrint(pTraceBuf,
3001                         TRACE_EVENT_MAX_SIZE,
3002                         (TRACE_EVENT_MAX_SIZE-1),
3003                         "IMTE|%d|%d", // magic number IMTE (IntelMediaTraceEvent)
3004                         usId,
3005                         ucType);
3006             nLen = strlen(pTraceBuf);
3007             if (pArg1)
3008             {
3009                 // convert raw event data to string. native raw data will be supported
3010                 // from linux kernel 4.10, hopefully we can skip this convert in the future.
3011                 const static char n2c[] = "0123456789ABCDEF";
3012                 unsigned char *pData = (unsigned char *)pArg1;
3013 
3014                 pTraceBuf[nLen++] = '|'; // prefix splite marker.
3015                 while(dwSize1-- > 0 && nLen < TRACE_EVENT_MAX_SIZE-2)
3016                 {
3017                     pTraceBuf[nLen++] = n2c[(*pData) >> 4];
3018                     pTraceBuf[nLen++] = n2c[(*pData++) & 0xf];
3019                 }
3020                 if (pArg2)
3021                 {
3022                     pData = (unsigned char *)pArg2;
3023                     while(dwSize2-- > 0 && nLen < TRACE_EVENT_MAX_SIZE-2)
3024                     {
3025                         pTraceBuf[nLen++] = n2c[(*pData) >> 4];
3026                         pTraceBuf[nLen++] = n2c[(*pData++) & 0xf];
3027                     }
3028                 }
3029             }
3030             size_t writeSize = write(MosTraceFd, pTraceBuf, nLen);
3031             MOS_FreeMemory(pTraceBuf);
3032         }
3033     }
3034     return;
3035 }
3036 
MOS_TraceDataDump(const char * pcName,uint32_t flags,const void * pBuf,uint32_t dwSize)3037 void MOS_TraceDataDump(
3038     const char * pcName,
3039     uint32_t     flags,
3040     const void * pBuf,
3041     uint32_t     dwSize)
3042 {
3043     // not implemented
3044 }
3045 
MOS_GfxInfoInit()3046 MOS_STATUS MOS_GfxInfoInit()
3047 {
3048     // not implemented
3049     return MOS_STATUS_SUCCESS;
3050 }
3051 
MOS_GfxInfoClose()3052 void MOS_GfxInfoClose()
3053 {
3054     // not implemented
3055 }
3056 
MOS_GfxInfo_RTErr(uint8_t ver,uint16_t compId,uint16_t FtrId,uint32_t ErrorCode,uint8_t num_of_triples,...)3057 void MOS_GfxInfo_RTErr(uint8_t ver,
3058     uint16_t    compId,
3059     uint16_t    FtrId,
3060     uint32_t    ErrorCode,
3061     uint8_t     num_of_triples,
3062     ...)
3063 {
3064     // not implemented
3065 }
3066 
MOS_GfxInfo(uint8_t ver,uint16_t compId,uint32_t tmtryID,uint8_t num_of_triples,...)3067 void MOS_GfxInfo(
3068     uint8_t         ver,
3069     uint16_t        compId,
3070     uint32_t        tmtryID,
3071     uint8_t         num_of_triples,
3072     ...)
3073 {
3074     // not implemented
3075 }
3076