| /* |
| * Copyright (c) 2009-2020, Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| //! |
| //! \file mos_utilities_specific.cpp |
| //! \brief This module implements the MOS wrapper functions for Linux/Android |
| //! |
| |
| #include "mos_utilities_specific.h" |
| #include "mos_utilities.h" |
| #include "mos_util_debug.h" |
| #include <fcntl.h> // open |
| #include <stdlib.h> // atoi |
| #include <string.h> // strlen, strcat, etc. |
| #include <errno.h> // strerror(errno) |
| #include <time.h> // get_clocktime |
| #include <sys/stat.h> // fstat |
| #include <dlfcn.h> // dlopen, dlsym, dlclose |
| #include <sys/types.h> |
| #include <unistd.h> |
| #if _MEDIA_RESERVED |
| #include "codechal_user_settings_mgr_ext.h" |
| #include "vphal_user_settings_mgr_ext.h" |
| #endif // _MEDIA_RESERVED |
| |
| #include <sys/ipc.h> // System V IPC |
| #include <sys/types.h> |
| #include <sys/sem.h> |
| #include <signal.h> |
| #include <unistd.h> // fork |
| #include "mos_utilities_specific_next.h" |
| static const char* szUserFeatureFile = USER_FEATURE_FILE; |
| |
| #if _MEDIA_RESERVED |
| static MediaUserSettingsMgr *codecUserFeatureExt = nullptr; |
| static MediaUserSettingsMgr *vpUserFeatureExt = nullptr; |
| #endif |
| |
| |
| #ifdef __cplusplus |
| |
| void PerfUtility::startTick(std::string tag) |
| { |
| std::lock_guard<std::mutex> lock(perfMutex); |
| Tick newTick = {}; |
| struct timespec ts = {}; |
| |
| // get start tick count |
| clock_gettime(CLOCK_REALTIME, &ts); |
| newTick.start = int(ts.tv_sec * 1000000) + int(ts.tv_nsec / 1000); // us |
| |
| std::vector<Tick> *perf = nullptr; |
| std::map<std::string, std::vector<Tick>*>::iterator it; |
| it = records.find(tag); |
| if (it == records.end()) |
| { |
| perf = new std::vector<Tick>; |
| perf->push_back(newTick); |
| records[tag] = perf; |
| } |
| else |
| { |
| it->second->push_back(newTick); |
| } |
| } |
| |
| void PerfUtility::stopTick(std::string tag) |
| { |
| std::lock_guard<std::mutex> lock(perfMutex); |
| struct timespec ts = {}; |
| std::map<std::string, std::vector<Tick>*>::iterator it; |
| it = records.find(tag); |
| if (it == records.end()) |
| { |
| // should not happen |
| return; |
| } |
| |
| // get stop tick count |
| clock_gettime(CLOCK_REALTIME, &ts); |
| it->second->back().stop = int(ts.tv_sec * 1000000) + int(ts.tv_nsec / 1000); // us |
| |
| // calculate time interval |
| it->second->back().time = double(it->second->back().stop - it->second->back().start) / 1000.0; // ms |
| } |
| |
| #endif // __cplusplus |
| |
| //! |
| //! \brief Linux specific user feature define, used in MOS_UserFeature_ParsePath |
| //! They can be unified with the win definitions, since they are identical. |
| //! |
| #define MOS_UF_SEPARATOR "\\" |
| #define MOS_UFKEY_EXT "UFKEY_EXTERNAL" |
| #define MOS_UFKEY_INT "UFKEY_INTERNAL" |
| PUFKEYOPS pUFKeyOps = nullptr; |
| |
| //! |
| //! \brief Linux specific trace entry path and file description. |
| //! |
| const char * const MosTracePath = "/sys/kernel/debug/tracing/trace_marker"; |
| static int32_t MosTraceFd = -1; |
| |
| //! |
| //! \brief for int64_t/uint64_t format print warning |
| //! |
| #if __WORDSIZE == 64 |
| #define __MOS64_PREFIX "l" |
| #else |
| #define __MOS64_PREFIX "ll" |
| #endif |
| |
| #define MOSd64 __MOS64_PREFIX "d" |
| #define MOSu64 __MOS64_PREFIX "u" |
| |
| //! |
| //! \brief mutex for mos utilities multi-threading protection |
| //! |
| MOS_MUTEX gMosUtilMutex = PTHREAD_MUTEX_INITIALIZER; |
| |
| static uint32_t uiMOSUtilInitCount = 0; // number count of mos utilities init |
| |
| MOS_STATUS MOS_SecureStrcat(char *strDestination, size_t numberOfElements, const char * const strSource) |
| { |
| if ( (strDestination == nullptr) || (strSource == nullptr) ) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if(strnlen(strDestination, numberOfElements) == numberOfElements) // Not null terminated |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if((strlen(strDestination) + strlen(strSource)) >= numberOfElements) // checks space for null termination. |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| strcat(strDestination, strSource); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| char *MOS_SecureStrtok( |
| char *strToken, |
| const char *strDelimit, |
| char **contex) |
| { |
| return strtok_r(strToken, strDelimit, contex); |
| } |
| |
| MOS_STATUS MOS_SecureStrcpy(char *strDestination, size_t numberOfElements, const char * const strSource) |
| { |
| if ( (strDestination == nullptr) || (strSource == nullptr) ) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if ( numberOfElements <= strlen(strSource) ) // checks if there is space for null termination after copy. |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| strcpy(strDestination, strSource); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_SecureMemcpy(void *pDestination, size_t dstLength, PCVOID pSource, size_t srcLength) |
| { |
| if ( (pDestination == nullptr) || (pSource == nullptr) ) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if ( dstLength < srcLength ) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| if(pDestination != pSource) |
| { |
| memcpy(pDestination, pSource, srcLength); |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_SecureFileOpen( |
| FILE **ppFile, |
| const char *filename, |
| const char *mode) |
| { |
| PFILE fp; |
| |
| if ((ppFile == nullptr) || (filename == nullptr) || (mode == nullptr)) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| fp = fopen(filename, mode); |
| |
| if (fp == nullptr) |
| { |
| *ppFile = nullptr; |
| return MOS_STATUS_FILE_OPEN_FAILED; |
| } |
| else |
| { |
| *ppFile = fp; |
| return MOS_STATUS_SUCCESS; |
| } |
| } |
| |
| int32_t MOS_SecureStringPrint(char *buffer, size_t bufSize, size_t length, const char * const format, ...) |
| { |
| int32_t iRet = -1; |
| va_list var_args; |
| |
| if((buffer == nullptr) || (format == nullptr) || (bufSize < length)) |
| { |
| return iRet; |
| } |
| |
| va_start(var_args, format); |
| |
| iRet = vsnprintf(buffer, length, format, var_args); |
| |
| va_end(var_args); |
| |
| return iRet; |
| } |
| |
| MOS_STATUS MOS_SecureVStringPrint(char *buffer, size_t bufSize, size_t length, const char * const format, va_list var_args) |
| { |
| if((buffer == nullptr) || (format == nullptr) || (bufSize < length)) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| vsnprintf(buffer, length, format, var_args); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_GetFileSize( |
| HANDLE hFile, |
| uint32_t *lpFileSizeLow, |
| uint32_t *lpFileSizeHigh) |
| { |
| struct stat Buf; |
| MOS_UNUSED(lpFileSizeHigh); |
| |
| if((hFile == nullptr) || (lpFileSizeLow == nullptr)) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if ( (fstat((intptr_t)hFile, &Buf)) < 0 ) |
| { |
| *lpFileSizeLow = 0; |
| return MOS_STATUS_INVALID_FILE_SIZE; |
| } |
| *lpFileSizeLow = (uint32_t)Buf.st_size; |
| |
| //to-do, lpFileSizeHigh store high 32-bit of File size |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_CreateDirectory( |
| char * const lpPathName) |
| { |
| uint32_t mode; |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| |
| MOS_OS_CHK_NULL(lpPathName); |
| |
| // Set read/write access right for usr/group. |
| mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP; |
| if (mkdir(lpPathName, mode) < 0 && |
| errno != EEXIST) // Directory already exists, don't return failure in this case. |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to create the directory '%s'. Error = %s", lpPathName, strerror(errno)); |
| eStatus = MOS_STATUS_DIR_CREATE_FAILED; |
| goto finish; |
| } |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| finish: |
| return eStatus; |
| } |
| |
| MOS_STATUS MOS_CreateFile( |
| PHANDLE pHandle, |
| char * const lpFileName, |
| uint32_t iOpenFlag) |
| { |
| int32_t iFileDescriptor; |
| uint32_t mode; |
| |
| if((lpFileName == nullptr) || (pHandle == nullptr)) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| //set read/write access right for usr/group, mMode only takes effect when |
| //O_CREAT is set |
| mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; |
| if ( (iFileDescriptor = open(lpFileName, iOpenFlag, mode)) < 0 ) |
| { |
| *pHandle = (HANDLE)((intptr_t) iFileDescriptor); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| |
| *pHandle = (HANDLE)((intptr_t) iFileDescriptor); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_ReadFile( |
| HANDLE hFile, |
| void *lpBuffer, |
| uint32_t bytesToRead, |
| uint32_t *pBytesRead, |
| void *lpOverlapped) |
| { |
| size_t nNumBytesToRead; |
| ssize_t nNumBytesRead; |
| MOS_UNUSED(lpOverlapped); |
| |
| if((hFile == nullptr) || (lpBuffer == nullptr) || (pBytesRead == nullptr)) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| nNumBytesToRead = (size_t)bytesToRead; |
| nNumBytesRead = 0; |
| |
| //To-do: process lpOverlapped |
| |
| if ((nNumBytesRead = read((intptr_t)hFile, lpBuffer, nNumBytesToRead)) < 0) |
| { |
| *pBytesRead = 0; |
| return MOS_STATUS_FILE_READ_FAILED; |
| } |
| |
| *pBytesRead = (uint32_t)nNumBytesRead; |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_WriteFile( |
| HANDLE hFile, |
| void *lpBuffer, |
| uint32_t bytesToWrite, |
| uint32_t *pbytesWritten, |
| void *lpOverlapped) |
| { |
| size_t nNumBytesToWrite; |
| ssize_t nNumBytesWritten; |
| MOS_UNUSED(lpOverlapped); |
| |
| if((hFile == nullptr) || (lpBuffer == nullptr) || (pbytesWritten == nullptr)) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| nNumBytesToWrite = (size_t)bytesToWrite; |
| nNumBytesWritten = 0; |
| |
| //To-do, process lpOverlapped |
| |
| if ((nNumBytesWritten = write((intptr_t)hFile, lpBuffer, nNumBytesToWrite)) < 0) |
| { |
| *pbytesWritten = 0; |
| return MOS_STATUS_FILE_WRITE_FAILED; |
| } |
| |
| *pbytesWritten = (uint32_t)nNumBytesWritten; |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_SetFilePointer( |
| HANDLE hFile, |
| int32_t lDistanceToMove, |
| int32_t *lpDistanceToMoveHigh, |
| int32_t dwMoveMethod) |
| { |
| int32_t iOffSet; |
| int32_t iCurPos; |
| |
| if(hFile == nullptr) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (lpDistanceToMoveHigh == nullptr) |
| { |
| iOffSet = lDistanceToMove; |
| } |
| else |
| { |
| //to-do, let lpDistanceToMoveHigh and lDistanceToMove form a 64-bit iOffSet |
| iOffSet = (int32_t)lDistanceToMove; |
| } |
| |
| if ((iCurPos = lseek((intptr_t)hFile, iOffSet, dwMoveMethod)) < 0) |
| { |
| return MOS_STATUS_SET_FILE_POINTER_FAILED; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| int32_t MOS_CloseHandle(HANDLE hObject) |
| { |
| int32_t iRet = false; |
| |
| if(hObject != nullptr) |
| { |
| close((intptr_t)hObject); |
| iRet = true; |
| } |
| |
| return iRet; |
| } |
| |
| //library |
| MOS_STATUS MOS_LoadLibrary(const char * const lpLibFileName, PHMODULE phModule) |
| { |
| if (lpLibFileName == nullptr) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| *phModule = dlopen((const char *)lpLibFileName, RTLD_LAZY); |
| |
| return ((*phModule != nullptr) ? MOS_STATUS_SUCCESS : MOS_STATUS_LOAD_LIBRARY_FAILED); |
| } |
| |
| int32_t MOS_FreeLibrary (HMODULE hLibModule) |
| { |
| uint32_t iRet = 10; // Initialize to some non-zero value |
| |
| if(hLibModule != nullptr) |
| { |
| iRet = dlclose(hLibModule); |
| } |
| return (iRet == 0) ? true : false; |
| } |
| |
| void *MOS_GetProcAddress(HMODULE hModule, const char *lpProcName) |
| { |
| void *pSym = nullptr; |
| |
| if (hModule == nullptr || |
| lpProcName == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid parameter."); |
| } |
| else |
| { |
| pSym = dlsym(hModule, lpProcName); |
| } |
| |
| return pSym; |
| } |
| |
| int32_t MOS_GetPid() |
| { |
| return(getpid()); |
| } |
| |
| //Performace |
| int32_t MOS_QueryPerformanceFrequency(uint64_t *pFrequency) |
| { |
| struct timespec Res; |
| int32_t iRet; |
| |
| if(pFrequency == nullptr) |
| { |
| return false; |
| } |
| |
| if ( (iRet = clock_getres(CLOCK_MONOTONIC, &Res)) != 0 ) |
| { |
| return false; |
| } |
| |
| // resolution (precision) can't be in seconds for current machine and OS |
| if (Res.tv_sec != 0) |
| { |
| return false; |
| } |
| *pFrequency = (uint64_t)((1000 * 1000 * 1000) / Res.tv_nsec); |
| |
| return true; |
| } |
| |
| int32_t MOS_QueryPerformanceCounter(uint64_t *pPerformanceCount) |
| { |
| struct timespec Res; |
| struct timespec t; |
| int32_t iRet; |
| |
| if(pPerformanceCount == nullptr) |
| { |
| return false; |
| } |
| if ( (iRet = clock_getres (CLOCK_MONOTONIC, &Res)) != 0 ) |
| { |
| return false; |
| } |
| if (Res.tv_sec != 0) |
| { // resolution (precision) can't be in seconds for current machine and OS |
| return false; |
| } |
| if( (iRet = clock_gettime(CLOCK_MONOTONIC, &t)) != 0) |
| { |
| return false; |
| } |
| *pPerformanceCount = (uint64_t)((1000 * 1000 * 1000 * t.tv_sec + t.tv_nsec) / Res.tv_nsec); |
| |
| return true; |
| } |
| |
| void MOS_Sleep(uint32_t mSec) |
| { |
| usleep(1000 * mSec); |
| } |
| |
| //User Feature |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_FindKey |
| | Purpose : This function finds a key in keys linked list according to key |
| | name. |
| | Arguments : pKeyList [in] Key Linked list. |
| | pcKeyName [in] Name to the key to find. |
| | Returns : Matched uf_key data. otherwise return NULL. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_UF_KEY* _UserFeature_FindKey(MOS_PUF_KEYLIST pKeyList, char * const pcKeyName) |
| { |
| int32_t iResult; |
| MOS_PUF_KEYLIST pTempNode; |
| |
| iResult = -1; |
| |
| for(pTempNode = pKeyList; pTempNode; pTempNode = pTempNode->pNext) |
| { |
| iResult = strcmp(pTempNode->pElem->pcKeyName, pcKeyName); |
| if ( iResult == 0 ) |
| { |
| return pTempNode->pElem; |
| } |
| } |
| return nullptr; //not found |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_FindValue |
| | Purpose : Find a value in values array of a key. Return position in values |
| | array |
| | Arguments : UFKey [in] Searched Key node. |
| | pcValueName [in] Value name. |
| | Returns : Matched value No. if it can be found, otherwise, return |
| | NOT_FOUND(-1); |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static int32_t _UserFeature_FindValue(MOS_UF_KEY UFKey, char * const pcValueName) |
| { |
| int32_t iResult; |
| int32_t i; |
| |
| iResult = -1; |
| |
| for ( i = 0; i < (int32_t)UFKey.ulValueNum; i++ ) |
| { |
| iResult = strcmp(UFKey.pValueArray[i].pcValueName, pcValueName); |
| if ( iResult == 0 ) |
| { |
| return i; |
| } |
| } |
| return NOT_FOUND; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_Add |
| | Purpose : Add new key to keys' linked list. |
| | Arguments : pKeyList [in] Key linked list. |
| | NewKey [in] Added new key. |
| | Returns : MOS_STATUS_SUCCESS success |
| | MOS_STATUS_INVALID_PARAMETER invalid NewKey |
| | MOS_STATUS_NO_SPACE no space left for allocate |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_Add(MOS_PUF_KEYLIST *pKeyList, MOS_UF_KEY *NewKey) |
| { |
| MOS_UF_KEYNODE *pNewNode; |
| MOS_UF_KEYNODE *pTempNode; |
| MOS_UF_KEYNODE *pStartNode; |
| |
| pNewNode = nullptr; |
| pTempNode = nullptr; |
| pStartNode = *pKeyList; |
| |
| if ( NewKey == nullptr ) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| pNewNode = (MOS_UF_KEYNODE*)MOS_AllocMemory(sizeof(MOS_UF_KEYNODE)); |
| if (pNewNode == nullptr) |
| { |
| return MOS_STATUS_NO_SPACE; |
| } |
| pNewNode->pElem = NewKey; |
| |
| if (*pKeyList == nullptr ) // the key list is empty |
| { |
| pNewNode->pNext = nullptr; |
| (*pKeyList) = pNewNode; |
| } |
| else // the key list is not empty, append to the front |
| { |
| pTempNode = pStartNode->pNext; |
| pStartNode->pNext = pNewNode; |
| pNewNode->pNext = pTempNode; |
| } |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_Set |
| | Purpose : This function set a key to the key list. |
| | Arguments : pKeyList [in] Key linked list. |
| | NewKey [in] Set key content. |
| | Returns : MOS_STATUS_SUCCESS Operation success. |
| | MOS_STATUS_UNKNOWN Can't find key in User Feature File. |
| | MOS_STATUS_NO_SPACE no space left for allocate |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_Set(MOS_PUF_KEYLIST *pKeyList, MOS_UF_KEY NewKey) |
| { |
| int32_t iPos; |
| MOS_UF_VALUE *pValueArray; |
| MOS_UF_KEY *Key; |
| void *ulValueBuf; |
| |
| iPos = -1; |
| pValueArray = nullptr; |
| |
| if ( (Key = _UserFeature_FindKey(*pKeyList, NewKey.pcKeyName)) == nullptr ) |
| { |
| // can't find key in File |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| // Prepare the ValueBuff of the NewKey |
| if ((ulValueBuf = MOS_AllocMemory(NewKey.pValueArray[0].ulValueLen)) == nullptr) |
| { |
| return MOS_STATUS_NO_SPACE; |
| } |
| |
| if ( (iPos = _UserFeature_FindValue(*Key, NewKey.pValueArray[0].pcValueName)) == NOT_FOUND) |
| { |
| //not found, add a new value to key struct. |
| //reallocate memory for appending this value. |
| pValueArray = (MOS_UF_VALUE*)MOS_AllocMemory(sizeof(MOS_UF_VALUE)*(Key->ulValueNum+1)); |
| if (pValueArray == nullptr) |
| { |
| MOS_FreeMemory(ulValueBuf); |
| return MOS_STATUS_NO_SPACE; |
| } |
| |
| MOS_SecureMemcpy(pValueArray, |
| sizeof(MOS_UF_VALUE)*(Key->ulValueNum), |
| Key->pValueArray, |
| sizeof(MOS_UF_VALUE)*(Key->ulValueNum)); |
| |
| MOS_FreeMemory(Key->pValueArray); |
| |
| Key->pValueArray = pValueArray; |
| |
| iPos = Key->ulValueNum; |
| MOS_SecureStrcpy(Key->pValueArray[Key->ulValueNum].pcValueName, |
| MAX_USERFEATURE_LINE_LENGTH, |
| NewKey.pValueArray[0].pcValueName); |
| Key->ulValueNum ++; |
| } |
| else |
| { |
| //if found, the previous value buffer needs to be freed before reallocating |
| MOS_FreeMemory(Key->pValueArray[iPos].ulValueBuf); |
| } |
| |
| Key->pValueArray[iPos].ulValueLen = NewKey.pValueArray[0].ulValueLen; |
| Key->pValueArray[iPos].ulValueType = NewKey.pValueArray[0].ulValueType; |
| Key->pValueArray[iPos].ulValueBuf = ulValueBuf; |
| |
| MOS_ZeroMemory(Key->pValueArray[iPos].ulValueBuf, NewKey.pValueArray[0].ulValueLen); |
| |
| MOS_SecureMemcpy(Key->pValueArray[iPos].ulValueBuf, |
| NewKey.pValueArray[0].ulValueLen, |
| NewKey.pValueArray[0].ulValueBuf, |
| NewKey.pValueArray[0].ulValueLen); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_Query |
| | Purpose : This function query a key's value and return matched key node |
| | content just with matched value content. |
| | Arguments : pKeyList [in] Key linked list. |
| | NewKey [in] New key content with matched value. |
| | Returns : MOS_STATUS_SUCCESS Operation success. |
| | MOS_STATUS_UNKNOWN Can't find key or value in User Feature File. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_Query(MOS_PUF_KEYLIST pKeyList, MOS_UF_KEY *NewKey) |
| { |
| int32_t iPos; |
| MOS_UF_VALUE *pValueArray; |
| MOS_UF_KEY *Key; |
| |
| iPos = -1; |
| pValueArray = nullptr; |
| |
| // can't find key in user feature |
| if ( (Key = _UserFeature_FindKey(pKeyList, NewKey->pcKeyName)) == nullptr ) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| // can't find Value in the key |
| if ( (iPos = _UserFeature_FindValue(*Key, NewKey->pValueArray[0].pcValueName)) == NOT_FOUND) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| //get key content from user feature |
| MOS_SecureMemcpy(NewKey->pValueArray[0].ulValueBuf, |
| Key->pValueArray[iPos].ulValueLen, |
| Key->pValueArray[iPos].ulValueBuf, |
| Key->pValueArray[iPos].ulValueLen); |
| |
| NewKey->pValueArray[0].ulValueLen = Key->pValueArray[iPos].ulValueLen; |
| NewKey->pValueArray[0].ulValueType = Key->pValueArray[iPos].ulValueType; |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| static MOS_STATUS _UserFeature_ReadNextTokenFromFile(FILE *pFile, const char *szFormat, char *szToken) |
| { |
| size_t nTokenSize = 0; |
| |
| // Reads the next token from the given pFile. |
| if (fscanf(pFile, szFormat, szToken) <= 0) |
| { |
| 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."); |
| return MOS_STATUS_FILE_READ_FAILED; |
| } |
| |
| // Converts to Unix-style line endings to prevent compatibility problems. |
| nTokenSize = strnlen(szToken, MAX_USERFEATURE_LINE_LENGTH); |
| if (szToken[nTokenSize-1] == '\r') |
| { |
| szToken[nTokenSize-1] = '\0'; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_DumpFile |
| | Purpose : This function read the whole User Feature File and dump User Feature File |
| | data to key linked list. |
| | Arguments : szFileName [in] User Feature File name. |
| | pKeyList [out] Key Linked list. |
| | Returns : MOS_STATUS_SUCCESS Operation success. |
| | MOS_STATUS_USER_FEATURE_KEY_READ_FAILED User Feature File can't be open as read. |
| | MOS_STATUS_NO_SPACE no space left for allocate |
| | MOS_STATUS_UNKNOWN unknown user feature type found in User Feature File |
| | MOS_STATUS_INVALID_PARAMETER unknown items found in User Feature File |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_DumpFile(const char * const szFileName, MOS_PUF_KEYLIST* pKeyList) |
| { |
| MOS_UF_KEY *CurKey; |
| MOS_UF_VALUE *CurValue; |
| char szTmp[MAX_USERFEATURE_LINE_LENGTH]; |
| int32_t iResult; |
| size_t nSize; |
| int32_t bFirst; |
| int32_t iCount; |
| PFILE File; |
| int32_t bEmpty; |
| int32_t iCurId; |
| MOS_STATUS eStatus; |
| char *tmpChar; // Used in the 64-bit case to read uint64_t |
| |
| CurValue = nullptr; |
| nSize = 0; |
| bFirst = 1; // 1 stand for "is the first key". |
| iCount = 0; |
| File = nullptr; |
| bEmpty = 0; |
| iCurId = 0; |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| CurKey = (MOS_UF_KEY*)MOS_AllocMemory(sizeof(MOS_UF_KEY)); |
| if (CurKey == nullptr) |
| { |
| return MOS_STATUS_NO_SPACE; |
| } |
| CurKey->ulValueNum = 0; |
| CurKey->pcKeyName[0] = '\0'; |
| CurKey->pValueArray = nullptr; |
| |
| if ( (File = fopen(szFileName, "r")) == nullptr) |
| { |
| MOS_FreeMemory(CurKey); |
| return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED; |
| } |
| while (feof(File) != EOF) |
| { |
| MOS_ZeroMemory(szTmp, MAX_USERFEATURE_LINE_LENGTH*sizeof(char )); |
| if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp))) |
| { |
| break; |
| } |
| |
| // set szDumpData with extracted File content. |
| iResult = strcmp(szTmp, UF_KEY_ID); |
| if ( iResult == 0 ) |
| { |
| // It is a new key starting! |
| if (! bFirst ) |
| { |
| // Add last key struct to contents when the key is not first. |
| // otherwise, continue to load key struct data. |
| CurKey->pValueArray = CurValue; |
| CurKey->ulValueNum = iCount; |
| if(_UserFeature_Add(pKeyList, CurKey) != MOS_STATUS_SUCCESS) |
| { |
| // if the CurKey didn't be added in pKeyList, free it. |
| MOS_FreeMemory(CurKey); |
| } |
| CurKey = (MOS_UF_KEY*)MOS_AllocMemory(sizeof(MOS_UF_KEY)); |
| if (CurKey == nullptr) |
| { |
| eStatus = MOS_STATUS_NO_SPACE; |
| break; |
| } |
| } // if (! bFirst ) |
| |
| if (fscanf(File, "%x\n", &iCurId) <= 0) |
| { |
| break; |
| } |
| |
| CurKey->UFKey = (void *)(intptr_t)iCurId; |
| |
| MOS_ZeroMemory(szTmp, MAX_USERFEATURE_LINE_LENGTH * sizeof(char)); |
| if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp))) |
| { |
| break; |
| } |
| |
| MOS_SecureStrcpy(CurKey->pcKeyName, MAX_USERFEATURE_LINE_LENGTH, szTmp); |
| CurKey->ulValueNum = 0; |
| |
| // allocate capability length for valuearray. |
| CurValue = (MOS_UF_VALUE*)MOS_AllocMemory(sizeof(MOS_UF_VALUE)*UF_CAPABILITY); |
| if (CurValue == nullptr) |
| { |
| eStatus = MOS_STATUS_NO_SPACE; |
| break; |
| } |
| bFirst = 0; |
| iCount = 0; // next key's array number. |
| bEmpty = 1; |
| } // if ( iResult == 0 ) |
| else // not a key |
| { |
| // Is it a value starting? |
| iResult = strcmp(szTmp, UF_VALUE_ID); |
| if ( iResult == 0 ) |
| { |
| if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp))) |
| { |
| break; |
| } |
| |
| if (CurValue == nullptr) |
| { |
| break; |
| } |
| |
| // Out of bounds technically based on how much memory we allocated |
| if (iCount < 0 || iCount >= UF_CAPABILITY) |
| { |
| eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED; |
| break; |
| } |
| |
| // Load value name; |
| MOS_SecureStrcpy(CurValue[iCount].pcValueName, MAX_USERFEATURE_LINE_LENGTH, szTmp); |
| |
| // Load value type |
| if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp))) |
| { |
| break; |
| } |
| |
| CurValue[iCount].ulValueType = atoi(szTmp); |
| |
| // Load value buffer. |
| switch ( CurValue[iCount].ulValueType ) |
| { |
| case UF_DWORD: // 32-bit |
| if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp))) |
| { |
| break; |
| } |
| |
| CurValue[iCount].ulValueLen = sizeof(uint32_t); |
| CurValue[iCount].ulValueBuf = MOS_AllocMemory(sizeof(uint32_t)); |
| if(CurValue[iCount].ulValueBuf == nullptr) |
| { |
| eStatus = MOS_STATUS_NO_SPACE; |
| break; |
| } |
| *(uint32_t*)(CurValue[iCount].ulValueBuf) = atoi(szTmp); |
| break; |
| case UF_QWORD: // 64-bit |
| if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp))) |
| { |
| break; |
| } |
| |
| CurValue[iCount].ulValueLen = sizeof(uint64_t); |
| CurValue[iCount].ulValueBuf = MOS_AllocMemory(sizeof(uint64_t)); |
| if(CurValue[iCount].ulValueBuf == nullptr) |
| { |
| eStatus = MOS_STATUS_NO_SPACE; |
| break; |
| } |
| tmpChar = &szTmp[0]; |
| *(uint64_t*)(CurValue[iCount].ulValueBuf) = strtoll(tmpChar,&tmpChar,0); |
| break; |
| case UF_SZ: |
| case UF_MULTI_SZ: |
| if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp))) |
| { |
| break; |
| } |
| |
| nSize = strlen(szTmp); |
| CurValue[iCount].ulValueLen = (nSize+1)*sizeof(char ); |
| CurValue[iCount].ulValueBuf = MOS_AllocMemory(nSize+1); |
| if(CurValue[iCount].ulValueBuf == nullptr) |
| { |
| eStatus = MOS_STATUS_NO_SPACE; |
| break; |
| } |
| MOS_ZeroMemory(CurValue[iCount].ulValueBuf, nSize+1); |
| MOS_SecureMemcpy(CurValue[iCount].ulValueBuf, nSize, szTmp, nSize); |
| break; |
| default: |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| break; |
| } |
| |
| iCount ++; // do the error checking near the top |
| |
| } // if ( iResult == 0 ) |
| else // It is not a value starting, it's bad User Feature File. |
| { |
| int32_t iResult = strcmp(szTmp, ""); |
| if ( !iResult ) |
| { |
| continue; |
| } |
| else |
| { |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| break; |
| } |
| } // else ( iResult == 0 ) |
| } |
| } // while (feof(File) != EOF) |
| |
| if (eStatus == MOS_STATUS_SUCCESS) |
| { |
| if ( bEmpty && (strlen(CurKey->pcKeyName) > 0) && |
| (CurKey->ulValueNum == 0) ) |
| { |
| CurKey->pValueArray = CurValue; |
| CurKey->ulValueNum = iCount; |
| if(_UserFeature_Add(pKeyList, CurKey) != MOS_STATUS_SUCCESS) |
| { |
| // if the CurKey didn't be added in pKeyList, free it. |
| for (uint32_t i = 0; i < iCount; i++) |
| { |
| if (CurValue) |
| { |
| MOS_FreeMemory(CurValue[i].ulValueBuf); |
| } |
| } |
| MOS_FreeMemory(CurValue); |
| MOS_FreeMemory(CurKey); |
| } |
| } |
| else |
| { |
| for (uint32_t i = 0; i < iCount; i++) |
| { |
| if (CurValue) |
| { |
| MOS_FreeMemory(CurValue[i].ulValueBuf); |
| } |
| } |
| MOS_FreeMemory(CurValue); |
| MOS_FreeMemory(CurKey); |
| } |
| } |
| else |
| { |
| for (uint32_t i = 0; i < iCount; i++) |
| { |
| if (CurValue) |
| { |
| MOS_FreeMemory(CurValue[i].ulValueBuf); |
| } |
| } |
| MOS_FreeMemory(CurValue); |
| MOS_FreeMemory(CurKey); |
| } |
| fclose(File); |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_DumpDataToFile |
| | Purpose : This function dump key linked list data to File. |
| | Arguments : szFileName [in] A handle to the File. |
| | pKeyList [in] Reserved, any LPDWORD type value. |
| | Returns : MOS_STATUS_SUCCESS Operation success. |
| | MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED File can't be written. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_DumpDataToFile(const char *szFileName, MOS_PUF_KEYLIST pKeyList) |
| { |
| int32_t iResult; |
| PFILE File; |
| MOS_PUF_KEYLIST pKeyTmp; |
| int32_t j; |
| |
| File = fopen(szFileName, "w+"); |
| if ( !File ) |
| { |
| return MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED; |
| } |
| |
| for (pKeyTmp = pKeyList; pKeyTmp; pKeyTmp = pKeyTmp->pNext) |
| { |
| fprintf(File, "%s\n", UF_KEY_ID); |
| fprintf(File, "\t0x%.8x\n", (uint32_t)(uintptr_t)pKeyTmp->pElem->UFKey); |
| fprintf(File, "\t%s\n", pKeyTmp->pElem->pcKeyName); |
| for ( j = 0; j < (int32_t)pKeyTmp->pElem->ulValueNum; j ++ ) |
| { |
| fprintf(File, "\t\t%s\n", UF_VALUE_ID); |
| if ( strlen(pKeyTmp->pElem->pValueArray[j].pcValueName) > 0 ) |
| { |
| fprintf(File, "\t\t\t%s\n", |
| pKeyTmp->pElem->pValueArray[j].pcValueName); |
| } |
| fprintf(File, "\t\t\t%d\n", pKeyTmp->pElem->pValueArray[j].ulValueType); |
| if (pKeyTmp->pElem->pValueArray[j].ulValueBuf != nullptr) |
| { |
| switch (pKeyTmp->pElem->pValueArray[j].ulValueType) |
| { |
| case UF_SZ: |
| fprintf(File, "\t\t\t%s\n", |
| (char *)(pKeyTmp->pElem->pValueArray[j].ulValueBuf)); |
| break; |
| case UF_DWORD: |
| case UF_QWORD: |
| fprintf(File, "\t\t\t%d\n", |
| *(uint32_t*)(pKeyTmp->pElem->pValueArray[j].ulValueBuf)); |
| break; |
| default: |
| fprintf(File, "\t\t\t%s\n", |
| (char *)(pKeyTmp->pElem->pValueArray[j].ulValueBuf)); |
| break; |
| } //switch (pKeyTmp->pElem->pValueArray[j].ulValueType) |
| } |
| } // for ( j = 0; j < (int32_t)pKeyTmp->pElem->ulValueNum; j ++ ) |
| } //for (pKeyTmp = pKeyList; pKeyTmp; pKeyTmp = pKeyTmp->pNext) |
| fclose(File); |
| MOS_UserFeatureNotifyChangeKeyValue(nullptr, false, nullptr, true); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_FreeKeyList |
| | Purpose : Free key list |
| | Arguments : pKeyList [in] key list to be free. |
| | Returns : None |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static void _UserFeature_FreeKeyList(MOS_PUF_KEYLIST pKeyList) |
| { |
| MOS_PUF_KEYLIST pKeyTmp; |
| MOS_PUF_KEYLIST pKeyTmpNext; |
| uint32_t i; |
| |
| pKeyTmp = pKeyList; |
| while(pKeyTmp) |
| { |
| pKeyTmpNext = pKeyTmp->pNext; |
| for(i=0;i<pKeyTmp->pElem->ulValueNum;i++) |
| { |
| MOS_FreeMemory(pKeyTmp->pElem->pValueArray[i].ulValueBuf); |
| } |
| MOS_FreeMemory(pKeyTmp->pElem->pValueArray); |
| MOS_FreeMemory(pKeyTmp->pElem); |
| MOS_FreeMemory(pKeyTmp); |
| pKeyTmp = pKeyTmpNext; |
| } |
| return; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_SetValue |
| | Purpose : Modify or add a value of the specified user feature key. |
| | Arguments : strKey [in] Pointer to user feature key name. |
| | pcValueName [in] Pointer to a string containing the name of |
| | the value to set. If a value with this name |
| | is not already present in the key, the |
| | function adds it to the key. |
| | uiValueType [in] Type of information to be stored. |
| | szValueData [in] Pointer to a null-terminated string |
| | containing the data to set for the default |
| | value of the specified key |
| | uiValueDataLen [in] Size of the string pointed to by the |
| | szValueData parameter, not including the |
| | terminating null character, in bytes |
| | Returns : MOS_STATUS_SUCCESS function success |
| | MOS_STATUS_INVALID_PARAMETER invalid paramater |
| | MOS_STATUS_USER_FEATURE_KEY_READ_FAILED User Feature File can't be open as read. |
| | MOS_STATUS_NO_SPACE no space left for allocate |
| | MOS_STATUS_UNKNOWN unknown user feature type found in User Feature File |
| | MOS_STATUS_INVALID_PARAMETER unknown items found in User Feature File |
| | MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED User Feature File can't be written. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_SetValue( |
| char * const strKey, |
| const char * const pcValueName, |
| uint32_t uiValueType, |
| void *pData, |
| int32_t nDataSize) |
| { |
| MOS_UF_KEY NewKey; |
| MOS_UF_VALUE NewValue; |
| MOS_STATUS eStatus; |
| MOS_PUF_KEYLIST pKeyList; |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| pKeyList = nullptr; |
| |
| if ( (strKey== nullptr) || (pcValueName == nullptr) ) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| MOS_ZeroMemory(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH); |
| MOS_SecureStrcpy(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH, pcValueName); |
| NewValue.ulValueType = uiValueType; |
| if( NewValue.ulValueType == UF_DWORD) |
| { |
| NewValue.ulValueLen = sizeof(uint32_t); |
| } |
| else |
| { |
| NewValue.ulValueLen = nDataSize; |
| } |
| NewValue.ulValueBuf = pData; |
| |
| MOS_ZeroMemory(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH); |
| MOS_SecureStrcpy(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH, strKey); |
| NewKey.pValueArray = &NewValue; |
| NewKey.ulValueNum = 1; |
| |
| if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) != MOS_STATUS_SUCCESS ) |
| { |
| _UserFeature_FreeKeyList(pKeyList); |
| return eStatus; |
| } |
| |
| if ( ( eStatus = _UserFeature_Set(&pKeyList, NewKey)) == MOS_STATUS_SUCCESS ) |
| { |
| eStatus = _UserFeature_DumpDataToFile(szUserFeatureFile, pKeyList); |
| } |
| |
| _UserFeature_FreeKeyList(pKeyList); |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_QueryValue |
| | Purpose : The QueryValue function retrieves the type and data for a |
| | specified value name associated with a special user feature key. |
| | Arguments : strKey [in] Pointer to user feature key name. |
| | pcValueName [in] Pointer to a string containing the name |
| | of the value to query. |
| | uiValueType [out] Output Value's type |
| | pData [out] Output value's content |
| | nDataSize [out] Output the size of value's content. |
| | Returns : MOS_STATUS_SUCCESS function success |
| | MOS_STATUS_INVALID_PARAMETER invalid paramater |
| | MOS_STATUS_USER_FEATURE_KEY_READ_FAILED User Feature File can't be open as read. |
| | MOS_STATUS_NO_SPACE no space left for allocate |
| | MOS_STATUS_UNKNOWN Can't find key or value in User Feature File. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_QueryValue( |
| char * const strKey, |
| const char * const pcValueName, |
| uint32_t *uiValueType, |
| void *pData, |
| int32_t *nDataSize) |
| { |
| MOS_UF_KEY NewKey; |
| MOS_UF_VALUE NewValue; |
| size_t nKeyLen, nValueLen; |
| MOS_STATUS eStatus; |
| MOS_PUF_KEYLIST pKeyList; |
| char strTempKey[MAX_USERFEATURE_LINE_LENGTH]; |
| char strTempValueName[MAX_USERFEATURE_LINE_LENGTH]; |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| pKeyList = nullptr; |
| |
| if ( (strKey == nullptr) || (pcValueName == nullptr)) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| MOS_ZeroMemory(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH); |
| MOS_SecureStrcpy(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH, pcValueName); |
| NewValue.ulValueBuf = pData; |
| |
| MOS_ZeroMemory(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH); |
| MOS_SecureStrcpy(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH, strKey); |
| NewKey.pValueArray = &NewValue; |
| NewKey.ulValueNum = 1; |
| |
| if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) == MOS_STATUS_SUCCESS) |
| { |
| if ( (eStatus = _UserFeature_Query(pKeyList, &NewKey)) == MOS_STATUS_SUCCESS ) |
| { |
| if(uiValueType != nullptr) |
| { |
| *uiValueType = NewKey.pValueArray[0].ulValueType; |
| } |
| if (nDataSize != nullptr) |
| { |
| *nDataSize = NewKey.pValueArray[0].ulValueLen; |
| } |
| } |
| } |
| _UserFeature_FreeKeyList(pKeyList); |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_GetKeyIdbyName |
| | Purpose : Get ID of the user feature key bu its name |
| | Arguments : pcKeyName [in] Pointer to user feature key name. |
| | pUFKey [out] A UFKEY pointer to store returned UFKey |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_GetKeyIdbyName(const char *pcKeyName, void **pUFKey) |
| { |
| MOS_PUF_KEYLIST pKeyList; |
| int32_t iResult; |
| MOS_STATUS eStatus; |
| MOS_PUF_KEYLIST pTempNode; |
| |
| pKeyList = nullptr; |
| iResult = -1; |
| |
| if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) != |
| MOS_STATUS_SUCCESS ) |
| { |
| _UserFeature_FreeKeyList(pKeyList); |
| return eStatus; |
| } |
| |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| |
| for(pTempNode=pKeyList; pTempNode; pTempNode=pTempNode->pNext) |
| { |
| iResult = strcmp(pTempNode->pElem->pcKeyName, pcKeyName); |
| if ( iResult == 0 ) |
| { |
| *pUFKey = pTempNode->pElem->UFKey; |
| eStatus = MOS_STATUS_SUCCESS; |
| break; |
| } |
| } |
| _UserFeature_FreeKeyList(pKeyList); |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : _UserFeature_GetKeyNamebyId |
| | Purpose : Get name of the user feature key bu its ID |
| | Arguments : UFKey [in] ID of the user feature key |
| | pcKeyName [out] To store user feature key name. |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| static MOS_STATUS _UserFeature_GetKeyNamebyId(void *UFKey, char *pcKeyName) |
| { |
| MOS_PUF_KEYLIST pKeyList; |
| MOS_PUF_KEYLIST pTempNode; |
| MOS_STATUS eStatus; |
| |
| pKeyList = nullptr; |
| |
| switch((uintptr_t)UFKey) |
| { |
| case UFKEY_INTERNAL: |
| MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_INTERNAL); |
| eStatus = MOS_STATUS_SUCCESS; |
| break; |
| case UFKEY_EXTERNAL: |
| MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_EXTERNAL); |
| eStatus = MOS_STATUS_SUCCESS; |
| break; |
| default: |
| if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) != |
| MOS_STATUS_SUCCESS ) |
| { |
| _UserFeature_FreeKeyList(pKeyList); |
| return eStatus; |
| } |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| |
| for(pTempNode=pKeyList;pTempNode;pTempNode=pTempNode->pNext) |
| { |
| if(pTempNode->pElem->UFKey == UFKey) |
| { |
| MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, pTempNode->pElem->pcKeyName); |
| eStatus = MOS_STATUS_SUCCESS; |
| break; |
| } |
| } |
| _UserFeature_FreeKeyList(pKeyList); |
| break; |
| } |
| |
| return eStatus; |
| |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_CheckMountStatus |
| | Purpose : check mount status |
| | Arguments : pKeyWord [in] Keyword for the Mountpoint |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_CheckMountStatus(char *pKeyWord) |
| { |
| char sPartitionPath[MAX_UF_PATH] = {'\0'}; |
| char sMountPoint[MAX_UF_PATH] = {'\0'}; |
| char sSystemType[MAX_UF_PATH] = {'\0'}; |
| char sTemp0[MAX_UF_PATH] = {'\0'}; |
| char sTemp1[MAX_UF_PATH] = {'\0'}; |
| char sTemp2[MAX_UF_PATH] = {'\0'}; |
| FILE* file; |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| |
| file = fopen("/proc/mounts", "r"); |
| MOS_OS_CHK_NULL(file); |
| MOS_OS_CHK_NULL(pKeyWord); |
| |
| while( fscanf( file, "%255s %255s %255s %255s %255s %255s\n", sPartitionPath, sMountPoint, sSystemType, sTemp0, sTemp1, sTemp2 ) > 0 ) |
| { |
| if( strcmp(sSystemType, pKeyWord) == 0 ) |
| { |
| eStatus = MOS_STATUS_SUCCESS; |
| break; |
| } |
| if( strcmp(sMountPoint, pKeyWord) == 0 ) |
| { |
| eStatus = MOS_STATUS_SUCCESS; |
| break; |
| } |
| } |
| finish: |
| if (file != nullptr) |
| { |
| fclose(file); |
| } |
| return eStatus; |
| } |
| #ifdef ANDROID |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_Strip_Chars |
| | Purpose : Strip some characters from a string |
| | Arguments : pstorestr [out] To store a striped string. |
| | pstring [in] string needed to be striped. |
| | pchars [in] stripped keyword. |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is an error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_StripChars(char *pstorestr, const char *pstring, const char *pchars) |
| { |
| int32_t counter = 0; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pstring); |
| MOS_OS_CHK_NULL(pchars); |
| |
| for ( ; *pstring; pstring++) |
| { |
| if (!strchr(pchars, *pstring)) |
| { |
| pstorestr[ counter ] = *pstring; |
| ++ counter; |
| } |
| } |
| pstorestr[counter] = 0; |
| finish: |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_InitAndroidPropInfo |
| | Purpose : Init Android Property Info |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_InitAndroidPropInfo() |
| { |
| char prop[MOS_USER_CONTROL_MAX_DATA_SIZE]; |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| int32_t ret; |
| int32_t iUFKeyEnable; |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| |
| eStatus = MOS_CheckMountStatus((char *)"/system"); |
| if (eStatus == MOS_STATUS_SUCCESS) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| if (property_get("debug.LibVa.RegKeyEnable", prop, nullptr) > 0) |
| { |
| if (sscanf(prop, "%d\n", &iUFKeyEnable) > 0) |
| { |
| if (iUFKeyEnable == 1) |
| { |
| eStatus = MOS_STATUS_SUCCESS; |
| } |
| } |
| } |
| } |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_GetAndroidPropPath |
| | Purpose : get AndroidProp path |
| | Arguments : pPath [out] store the path |
| | pUserFeature [in] User Feature data for input User Feature Key |
| | FuncType [in] Read/Write Type |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_GetAndroidPropPath( |
| char *pPath, |
| PMOS_USER_FEATURE_VALUE pUserFeature, |
| LINUX_UF_FUNC_TYPE FuncType) |
| { |
| |
| char sPath[MAX_UF_PATH]; |
| char sKey[MAX_UF_PATH]; |
| char sFuncType[MAX_UF_PATH]; |
| char pPrefixPath[MAX_UF_PATH]; |
| char sUFName[MAX_UF_PATH]; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| MOS_OS_CHK_NULL(pUserFeature); |
| MOS_OS_CHK_NULL(pPath); |
| |
| MOS_ZeroMemory(sPath, MAX_UF_PATH); |
| MOS_ZeroMemory(sKey, MAX_UF_PATH); |
| switch(pUserFeature->Type) |
| { |
| case MOS_USER_FEATURE_TYPE_USER: |
| MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFINT_PATH_LINUX); |
| break; |
| case MOS_USER_FEATURE_TYPE_SYSTEM: |
| MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFEXT_PATH_LINUX); |
| break; |
| default: |
| MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFINT_PATH_LINUX); |
| break; |
| }// switch |
| |
| MOS_ZeroMemory(sFuncType, MAX_UF_PATH); |
| switch(FuncType) |
| { |
| case LINUX_UF_FUNCTYPE_READ: |
| MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcPath); |
| break; |
| case LINUX_UF_FUNCTYPE_WRITE: |
| MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcWritePath); |
| break; |
| default: |
| MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcPath); |
| break; |
| }// switch |
| |
| MOS_OS_CHK_STATUS(MOS_StripChars(sUFName,pUserFeature->pValueName," ")); |
| snprintf( |
| sPath, |
| sizeof(sPath), |
| "%s.%s.%s", |
| sKey, |
| sFuncType, |
| sUFName); |
| |
| MOS_SecureMemcpy(pPath, strlen(sPath)+1, sPath, strlen(sPath)+1); |
| finish: |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_AndroidPropOpenKey |
| | Purpose : open a file for AndroidProp |
| | Arguments : pPath [in] |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_AndroidPropOpenKey( |
| char *pPath) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_FILE_OPEN_FAILED; |
| char prop[MOS_USER_CONTROL_MAX_DATA_SIZE]; |
| MOS_OS_CHK_NULL(pPath); |
| |
| if (property_get(pPath, prop, nullptr) > 0) |
| { |
| eStatus = MOS_STATUS_SUCCESS; |
| } |
| finish: |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_AndroidPropWriteValue |
| | Purpose : write a AndroidProp User Feature Data Value |
| | Arguments : pPath [in] |
| | pUserData [in] user feature key write value |
| | ValueType [in] Type of Data |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_AndroidPropWriteValue( |
| char *pPath, |
| PMOS_USER_FEATURE_VALUE_DATA pUserData, |
| MOS_USER_FEATURE_VALUE_TYPE ValueType) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED; |
| char prop[MOS_USER_CONTROL_MAX_DATA_SIZE]; |
| int32_t ret = 0; |
| MOS_OS_CHK_NULL(pPath); |
| MOS_OS_CHK_NULL(pUserData); |
| |
| switch(ValueType) |
| { |
| case MOS_USER_FEATURE_VALUE_TYPE_BOOL: |
| ret = snprintf(prop, sizeof(prop), "%d\n", pUserData->bData); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_INT32: |
| ret = snprintf(prop, sizeof(prop), "%d\n", pUserData->i32Data); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_UINT32: |
| ret = snprintf(prop, sizeof(prop), "%u\n", pUserData->u32Data); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_INT64: |
| ret = snprintf(prop, sizeof(prop), "%" MOSd64 "\n", pUserData->i64Data); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_UINT64: |
| ret = snprintf(prop, sizeof(prop), "%" MOSu64 "\n", pUserData->u64Data); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_STRING: |
| if ((pUserData->StringData.pStringData != nullptr) && (strlen(pUserData->StringData.pStringData) != 0)) |
| { |
| ret = snprintf(prop, sizeof(prop), "%s\n", pUserData->StringData.pStringData); |
| } |
| break; |
| default: |
| break; |
| } |
| if (ret > 0) |
| { |
| ret = property_set(pPath, prop); |
| if (ret == 0) |
| { |
| eStatus = MOS_STATUS_SUCCESS; |
| } |
| } |
| finish: |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_AndroidPropCreateKey |
| | Purpose : set default value to AndroidProp User Feature Key according to userfeature |
| | Arguments : pUserFeature [in] value for ceated key |
| | FuncType [in] Type of function |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_AndroidPropCreateKey( |
| PMOS_USER_FEATURE_VALUE pUserFeature, |
| LINUX_UF_FUNC_TYPE FuncType) |
| { |
| char sPath[MAX_UF_PATH]; |
| MOS_STATUS eStatus = MOS_STATUS_DIR_CREATE_FAILED; |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| MOS_USER_FEATURE_VALUE_TYPE ValueType = MOS_USER_FEATURE_VALUE_TYPE_INVALID; |
| char prop[MOS_USER_CONTROL_MAX_DATA_SIZE]; |
| int32_t ret; |
| |
| MOS_OS_CHK_NULL(pUserFeature); |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| |
| // create key |
| MOS_ZeroMemory(sPath, MAX_UF_PATH); |
| MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, FuncType)); |
| // set the default Data and Type value according to default value and type in pUserFeature. |
| MOS_OS_CHK_STATUS(MOS_AndroidPropWriteValue(sPath, &pUserFeature->Value, pUserFeature->ValueType)); |
| finish: |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_AndroidPropReadValue |
| | Purpose : read a AndroidProp User Feature Data Value |
| | Arguments : pPath [in] |
| | pUserData [out] To store user feature key value. |
| | ValueType [in] Type of Data |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_AndroidPropReadValue( |
| char *pPath, |
| PMOS_USER_FEATURE_VALUE_DATA pUserData, |
| MOS_USER_FEATURE_VALUE_TYPE ValueType) |
| { |
| MOS_USER_FEATURE_VALUE_DATA UserData; |
| char pcTmpStr[MOS_USER_CONTROL_MAX_DATA_SIZE]; |
| MOS_STATUS eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED; |
| char prop[MOS_USER_CONTROL_MAX_DATA_SIZE]; |
| int32_t ret = 0; |
| |
| MOS_OS_CHK_NULL(pPath); |
| MOS_OS_CHK_NULL(pUserData); |
| |
| MOS_ZeroMemory(&UserData, sizeof(UserData)); |
| |
| if (property_get(pPath, prop, nullptr) > 0) |
| { |
| switch(ValueType) |
| { |
| case MOS_USER_FEATURE_VALUE_TYPE_BOOL: |
| ret = sscanf(prop, "%d\n", &pUserData->bData); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_INT32: |
| ret = sscanf(prop, "%d\n", &pUserData->i32Data); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_UINT32: |
| ret = sscanf(prop, "%u\n", &pUserData->u32Data); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_INT64: |
| ret = sscanf(prop, "%" MOSd64 "\n", &pUserData->i64Data); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_UINT64: |
| ret = sscanf(prop, "%" MOSu64 "\n", &pUserData->u64Data); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_STRING: |
| if( sscanf( prop, "%s\n", pcTmpStr) > 0 ) |
| { |
| if (strlen(pcTmpStr) > 0) |
| { |
| MOS_SafeFreeMemory(pUserData->StringData.pStringData); |
| pUserData->StringData.pStringData = (char *)MOS_AllocAndZeroMemory(strlen(pcTmpStr)+1); |
| MOS_SecureMemcpy(pUserData->StringData.pStringData, strlen(pcTmpStr), pcTmpStr, MOS_MIN(strlen(pcTmpStr), MOS_USER_CONTROL_MAX_DATA_SIZE)); |
| pUserData->StringData.uSize = strlen(pcTmpStr); |
| ret = pUserData->StringData.uSize; |
| } |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| if (ret > 0) |
| { |
| eStatus = MOS_STATUS_SUCCESS; |
| } |
| finish: |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_UserFeatureOpenKey_AndroidProp |
| | Purpose : Opens the specified user feature key. |
| | Arguments : UFKey [in] A handle to an open user feature key. |
| | lpSubKey [in] The name of the user feature subkey to be opened. |
| | ulOptions [in] This parameter is reserved and must be zero. |
| | samDesired [in] Reserved, could be any REGSAM type value |
| | phkResult [out] A pointer to a variable that receives a handle |
| | to the opened key. |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_UserFeatureOpenKey_AndroidProp( |
| void *UFKey, |
| const char *lpSubKey, |
| uint32_t ulOptions, |
| uint32_t samDesired, |
| void **phkResult) |
| { |
| char pcKeyName[MAX_USERFEATURE_LINE_LENGTH]; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| PMOS_USER_FEATURE_VALUE pUserFeature = nullptr; |
| char sPath[MAX_UF_PATH]; |
| LINUX_UF_FUNC_TYPE FuncType = LINUX_UF_FUNCTYPE_INVALID; |
| MOS_UNUSED(UFKey); |
| MOS_UNUSED(ulOptions); |
| |
| MOS_OS_CHK_NULL(lpSubKey); |
| pUserFeature = (PMOS_USER_FEATURE_VALUE)*phkResult; |
| MOS_OS_CHK_NULL(pUserFeature); |
| if( strcmp(lpSubKey, pUserFeature->pcWritePath) == 0 ) |
| { |
| FuncType = LINUX_UF_FUNCTYPE_WRITE; |
| } |
| else if( strcmp(lpSubKey, pUserFeature->pcPath) == 0 ) |
| { |
| FuncType = LINUX_UF_FUNCTYPE_READ; |
| } |
| MOS_ZeroMemory(sPath, MAX_UF_PATH); |
| MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, FuncType)); |
| if (MOS_AndroidPropOpenKey(sPath) != MOS_STATUS_SUCCESS) |
| { |
| // No Sub Key return directly |
| eStatus = MOS_STATUS_FILE_OPEN_FAILED; |
| // KEY_WRITE |
| if (samDesired == KEY_WRITE) |
| { |
| if (MOS_AndroidPropCreateKey(pUserFeature, FuncType) != MOS_STATUS_SUCCESS) |
| { |
| eStatus = MOS_STATUS_DIR_CREATE_FAILED; |
| } |
| } |
| else |
| { |
| eStatus = MOS_STATUS_FILE_OPEN_FAILED; |
| } |
| } |
| finish: |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_UserFeatureGetValue_AndroidProp |
| | Purpose : Retrieves the type and data for the specified user feature value. |
| | Arguments : UFKey [in] A handle to an open user feature key. |
| | lpSubKey [in] The name of the user feature key. This key must be a |
| | subkey of the key specified by the UFKey parameter |
| | lpValue [in] The name of the user feature value. |
| | dwFlags [in] Reserved, could be any uint32_t type value |
| | pdwType [out] A pointer to a variable that receives a code |
| | indicating the type of data stored in the |
| | specified value. |
| | pvData [out] A pointer to a buffer that receives the value's |
| | data. |
| | pcbData [out] A pointer to a variable that specifies the size |
| | of the buffer pointed to by the pvData parameter, |
| | in bytes. |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_UserFeatureGetValue_AndroidProp( |
| void *UFKey, |
| const char *lpSubKey, |
| const char *lpValue, |
| uint32_t dwFlags, |
| uint32_t *pdwType, |
| void *pvData, |
| uint32_t *pcbData) |
| { |
| char pcKeyName[MAX_USERFEATURE_LINE_LENGTH]; |
| int32_t dData; |
| int32_t index = 0; |
| PMOS_USER_FEATURE_VALUE pSettingsValue; |
| PMOS_USER_FEATURE_VALUE pUserFeature = nullptr; |
| char sPath[MAX_UF_PATH]; |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| MOS_UNUSED(lpSubKey); |
| MOS_UNUSED(lpValue); |
| MOS_UNUSED(dwFlags); |
| MOS_UNUSED(pdwType); |
| |
| if(UFKey == nullptr) |
| { |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| goto finish; |
| } |
| pUserFeature = (PMOS_USER_FEATURE_VALUE)UFKey; |
| |
| MOS_ZeroMemory(sPath, MAX_UF_PATH); |
| MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, LINUX_UF_FUNCTYPE_READ)); |
| |
| // Read Type |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| if (MOS_AndroidPropReadValue(sPath, &UserFeatureData, pUserFeature->ValueType) == MOS_STATUS_SUCCESS) |
| { |
| // get key content from user feature |
| switch(pUserFeature->ValueType) |
| { |
| case MOS_USER_FEATURE_VALUE_TYPE_BINARY: |
| *(int32_t*)pvData = UserFeatureData.bData; |
| *(uint32_t*)pcbData = sizeof(int32_t); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_INT32: |
| *(int32_t*)pvData = UserFeatureData.i32Data; |
| *(uint32_t*)pcbData = sizeof(int32_t); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_INT64: |
| *(int64_t*)pvData = UserFeatureData.i64Data; |
| *(uint32_t*)pcbData = sizeof(int64_t); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_UINT32: |
| *(uint32_t*)pvData = UserFeatureData.u32Data; |
| *(uint32_t*)pcbData = sizeof(uint32_t); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_UINT64: |
| *(uint64_t*)pvData = UserFeatureData.u64Data; |
| *(uint32_t*)pcbData = sizeof(uint64_t); |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_STRING: |
| MOS_SecureMemcpy(pvData, UserFeatureData.StringData.uSize, UserFeatureData.StringData.pStringData, UserFeatureData.StringData.uSize); |
| MOS_SafeFreeMemory(UserFeatureData.StringData.pStringData); |
| *(uint32_t*)pcbData = UserFeatureData.StringData.uSize; |
| break; |
| default: |
| break; |
| }// switch |
| } |
| else |
| { |
| eStatus = MOS_STATUS_FILE_NOT_FOUND; |
| } |
| finish: |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_UserFeatureSetValueEx_AndroidProp |
| | Purpose : Sets the data and type of a specified value under a user feature key. |
| | Arguments : UFKey [in] A handle to an open user feature key. |
| | lpValueName [in] The name of the user feature value. |
| | Reserved [in] This parameter is reserved and must be NULL. |
| | dwType [in] The type of data pointed to by the lpData |
| | parameter. |
| | lpData [in] The data to be stored. |
| | cbData [in] The size of the information pointed to by the |
| | lpData parameter, in bytes. |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_UserFeatureSetValueEx_AndroidProp( |
| void *UFKey, |
| const char *lpValueName, |
| uint32_t Reserved, |
| uint32_t dwType, |
| uint8_t *lpData, |
| uint32_t cbData) |
| { |
| char pcKeyName[MAX_USERFEATURE_LINE_LENGTH]; |
| int32_t dData; |
| int32_t index = 0; |
| uint32_t ui; |
| PMOS_USER_FEATURE_VALUE pUserFeature = nullptr; |
| char sPath[MAX_UF_PATH]; |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| MOS_USER_FEATURE_VALUE_TYPE ValueType = MOS_USER_FEATURE_VALUE_TYPE_INVALID; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| MOS_UNUSED(lpValueName); |
| MOS_UNUSED(Reserved); |
| MOS_UNUSED(dwType); |
| |
| if(UFKey == nullptr) |
| { |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| goto finish; |
| } |
| pUserFeature = (PMOS_USER_FEATURE_VALUE)UFKey; |
| for (ui = 0; ui < pUserFeature->uiNumOfValues; ui++) |
| { |
| // Check the Key exist or not |
| MOS_ZeroMemory(sPath, MAX_UF_PATH); |
| MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, LINUX_UF_FUNCTYPE_WRITE)); |
| |
| if (MOS_AndroidPropOpenKey(sPath) != MOS_STATUS_SUCCESS){ |
| // create the Key according to pFeatureValue->ValueType |
| if( MOS_AndroidPropCreateKey(pUserFeature, LINUX_UF_FUNCTYPE_WRITE) != MOS_STATUS_SUCCESS ) |
| { |
| eStatus = MOS_STATUS_DIR_CREATE_FAILED; |
| goto finish; |
| } |
| } |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| ValueType = (MOS_USER_FEATURE_VALUE_TYPE)pUserFeature->ValueType; |
| switch(ValueType) |
| { |
| case MOS_USER_FEATURE_VALUE_TYPE_BINARY: |
| UserFeatureData.bData =*(int32_t*)lpData ; |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_INT32: |
| UserFeatureData.i32Data =*(int32_t*)lpData ; |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_INT64: |
| UserFeatureData.i64Data =*(int64_t*)lpData; |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_UINT32: |
| UserFeatureData.u32Data = *(uint32_t*)lpData; |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_UINT64: |
| UserFeatureData.u64Data =*(uint64_t*)lpData; |
| break; |
| case MOS_USER_FEATURE_VALUE_TYPE_STRING: |
| UserFeatureData.StringData.pStringData =(char *)lpData; |
| UserFeatureData.StringData.uSize = cbData; |
| break; |
| default: |
| break; |
| }//switch |
| if (MOS_AndroidPropWriteValue(sPath, &UserFeatureData, ValueType) != MOS_STATUS_SUCCESS) |
| { |
| eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED; |
| goto finish; |
| } |
| } |
| finish: |
| return eStatus; |
| } |
| #endif |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_UserFeatureOpenKey_File |
| | Purpose : Opens the specified user feature key. |
| | Arguments : UFKey [in] A handle to an open user feature key. |
| | lpSubKey [in] The name of the user feature subkey to be opened. |
| | ulOptions [in] This parameter is reserved and must be zero. |
| | samDesired [in] Reserved, could be any REGSAM type value |
| | phkResult [out] A pointer to a variable that receives a handle |
| | to the opened key. |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_UserFeatureOpenKey_File( |
| void *UFKey, |
| const char *lpSubKey, |
| uint32_t ulOptions, // reserved |
| uint32_t samDesired, |
| void **phkResult) |
| { |
| char pcKeyName[MAX_USERFEATURE_LINE_LENGTH]; |
| MOS_STATUS iRet; |
| uintptr_t h_key = (uintptr_t)UFKey; |
| MOS_UNUSED(ulOptions); |
| MOS_UNUSED(samDesired); |
| |
| if((h_key == 0) /*|| (lpSubKey == nullptr)*/ || (phkResult == nullptr)) //[SH]: subkey can be NULL??? |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH*sizeof(char)); |
| switch(h_key) |
| { |
| case UFKEY_INTERNAL: |
| MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_INTERNAL); |
| break; |
| case UFKEY_EXTERNAL: |
| MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_EXTERNAL); |
| break; |
| default: |
| break; |
| } |
| |
| MOS_SecureStrcat(pcKeyName, sizeof(pcKeyName), lpSubKey); |
| iRet = _UserFeature_GetKeyIdbyName(pcKeyName, phkResult); |
| |
| return iRet; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_UserFeatureGetValue_File |
| | Purpose : Retrieves the type and data for the specified user feature value. |
| | Arguments : UFKey [in] A handle to an open user feature key. |
| | lpSubKey [in] The name of the user feature key. This key must be a |
| | subkey of the key specified by the UFKey parameter |
| | lpValue [in] The name of the user feature value. |
| | dwFlags [in] Reserved, could be any uint32_t type value |
| | pdwType [out] A pointer to a variable that receives a code |
| | indicating the type of data stored in the |
| | specified value. |
| | pvData [out] A pointer to a buffer that receives the value's |
| | data. |
| | pcbData [out] A pointer to a variable that specifies the size |
| | of the buffer pointed to by the pvData parameter, |
| | in bytes. |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_UserFeatureGetValue_File( |
| void *UFKey, |
| const char *lpSubKey, |
| const char *lpValue, |
| uint32_t dwFlags, |
| uint32_t *pdwType, |
| void *pvData, |
| uint32_t *pcbData) |
| { |
| char pcKeyName[MAX_USERFEATURE_LINE_LENGTH]; |
| MOS_STATUS eStatus; |
| MOS_UNUSED(dwFlags); |
| |
| if(UFKey == nullptr) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH * sizeof(char)); |
| if ( (eStatus = _UserFeature_GetKeyNamebyId(UFKey,pcKeyName)) != MOS_STATUS_SUCCESS) |
| { |
| return eStatus; |
| } |
| |
| if(lpSubKey != nullptr) |
| { |
| MOS_SecureStrcat(pcKeyName, sizeof(pcKeyName), lpSubKey); |
| } |
| eStatus = _UserFeature_QueryValue(pcKeyName, |
| lpValue, |
| (uint32_t*)pdwType, |
| pvData, |
| (int32_t*)pcbData); |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : MOS_UserFeatureSetValueEx_File |
| | Purpose : Sets the data and type of a specified value under a user feature key. |
| | Arguments : UFKey [in] A handle to an open user feature key. |
| | lpValueName [in] The name of the user feature value. |
| | Reserved in] This parameter is reserved and must be NULL. |
| | dwType [in] The type of data pointed to by the lpData |
| | parameter. |
| | lpData [in] The data to be stored. |
| | cbData [in] The size of the information pointed to by the |
| | lpData parameter, in bytes. |
| | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS. |
| | If the function fails, the return value is a error code defined |
| | in mos_utilities.h. |
| | Comments : |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS MOS_UserFeatureSetValueEx_File( |
| void *UFKey, |
| const char *lpValueName, |
| uint32_t Reserved, |
| uint32_t dwType, |
| uint8_t *lpData, |
| uint32_t cbData) |
| { |
| char pcKeyName[MAX_USERFEATURE_LINE_LENGTH]; |
| MOS_STATUS eStatus; |
| MOS_UNUSED(Reserved); |
| |
| if (UFKey == nullptr) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH*sizeof(char)); |
| if ((eStatus = _UserFeature_GetKeyNamebyId(UFKey,pcKeyName)) != MOS_STATUS_SUCCESS) |
| { |
| return eStatus; |
| } |
| |
| eStatus = _UserFeature_SetValue(pcKeyName,lpValueName,dwType,lpData,cbData); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS MOS_UserFeatureOpenKey( |
| void *ufKey, |
| const char *lpSubKey, |
| uint32_t ulOptions, |
| uint32_t samDesired, |
| void **phkResult, |
| MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo) |
| { |
| return MosUtilities::MosUserFeatureOpenKey( |
| ufKey, |
| lpSubKey, |
| ulOptions, |
| samDesired, |
| phkResult, |
| ufInfo); |
| } |
| |
| MOS_STATUS MOS_UserFeatureCloseKey(void *UFKey) |
| { |
| MOS_UNUSED(UFKey); |
| //always return success, because we actually dong't have a key opened. |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_UserFeatureGetValue( |
| void *UFKey, |
| const char *lpSubKey, |
| const char *lpValue, |
| uint32_t dwFlags, |
| uint32_t *pdwType, |
| void *pvData, |
| uint32_t *pcbData) |
| { |
| char pcKeyName[MAX_USERFEATURE_LINE_LENGTH]; |
| MOS_STATUS eStatus; |
| |
| if(UFKey == nullptr) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| if (( pUFKeyOps != nullptr) && (pUFKeyOps->pfnUserFeatureGetValue != nullptr)) |
| { |
| return pUFKeyOps->pfnUserFeatureGetValue(UFKey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); |
| } |
| else |
| { |
| return MOS_UserFeatureGetValue_File(UFKey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); |
| } |
| |
| } |
| |
| MOS_STATUS MOS_UserFeatureQueryValueEx( |
| void *UFKey, |
| char *lpValueName, |
| uint32_t *lpReserved, |
| uint32_t *lpType, |
| char *lpData, |
| uint32_t *lpcbData) |
| { |
| MOS_UNUSED(lpReserved); |
| return MOS_UserFeatureGetValue(UFKey, "", lpValueName, 0, lpType, lpData, lpcbData); |
| } |
| |
| MOS_STATUS MOS_UserFeatureSetValueEx( |
| void *UFKey, |
| const char *lpValueName, |
| uint32_t Reserved, |
| uint32_t dwType, |
| uint8_t *lpData, |
| uint32_t cbData) |
| { |
| char pcKeyName[MAX_USERFEATURE_LINE_LENGTH]; |
| MOS_STATUS eStatus; |
| |
| if (UFKey == nullptr) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (dwType == UF_SZ || dwType == UF_MULTI_SZ) |
| { |
| if (lpData == nullptr || strlen((const char*)lpData) == 0) |
| { |
| MOS_OS_NORMALMESSAGE("NULL string, skip to report"); |
| return MOS_STATUS_SUCCESS; |
| } |
| } |
| |
| if (( pUFKeyOps != nullptr) && (pUFKeyOps->pfnUserFeatureSetValueEx!= nullptr)) |
| { |
| return pUFKeyOps->pfnUserFeatureSetValueEx(UFKey, lpValueName, Reserved, dwType, lpData, cbData); |
| } |
| else |
| { |
| return MOS_UserFeatureSetValueEx_File(UFKey, lpValueName, Reserved, dwType, lpData, cbData); |
| } |
| } |
| |
| // Event Related Functions: Android does not support these |
| #ifndef ANDROID |
| MOS_STATUS MOS_UserFeatureNotifyChangeKeyValue( |
| void *UFKey, |
| int32_t bWatchSubtree, |
| HANDLE hEvent, |
| int32_t fAsynchronous) |
| { |
| key_t key; |
| int32_t semid; |
| struct sembuf operation[1] ; |
| |
| key = ftok(szUserFeatureFile,1); |
| semid = semget(key,1,0); |
| //change semaphore |
| operation[0].sem_op = 1; |
| operation[0].sem_num = 0; |
| operation[0].sem_flg = SEM_UNDO; |
| semop(semid, operation, 1); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| HANDLE MOS_CreateEventEx( |
| void *lpEventAttributes, |
| char *lpName, |
| uint32_t dwFlags) |
| { |
| int32_t semid; |
| key_t key; |
| union semun |
| { |
| int32_t val; |
| struct semid_ds *Buf; |
| unsigned short *array; |
| } semctl_arg; |
| |
| semid = 0; |
| |
| //Generate a unique key, U can also supply a value instead |
| key = ftok(szUserFeatureFile, 1); |
| semid = semget(key, 1, 0666 | IPC_CREAT ); |
| semctl_arg.val = 0; //Setting semval to 0 |
| semctl(semid, 0, SETVAL, semctl_arg); |
| |
| HANDLE ret = reinterpret_cast<HANDLE>(semid); |
| |
| return ret; |
| } |
| |
| int32_t MOS_UserFeatureWaitForSingleObject( |
| PTP_WAIT* phNewWaitObject, |
| HANDLE hObject, |
| void *Callback, |
| void *Context) |
| { |
| int32_t iRet; |
| int32_t semid; |
| struct sembuf operation[1]; |
| pid_t pid; |
| MOS_UserFeatureCallback pCallback; |
| LARGE_INTEGER largeInteger; |
| |
| pCallback = (MOS_UserFeatureCallback)Callback; |
| |
| iRet = 0; |
| |
| largeInteger.QuadPart = (int64_t)hObject; |
| |
| semid = largeInteger.u.LowPart; |
| |
| if ((pid=fork()) == -1) |
| { |
| printf("error\n"); |
| } |
| else if(pid == 0) |
| { |
| while(1) |
| { |
| operation[0].sem_op = -1; |
| operation[0].sem_num = 0; |
| //now waiting |
| semop(semid, operation, 1); |
| pCallback(Context, 0); |
| } |
| exit(0); |
| } |
| else |
| { |
| iRet = pid; |
| } |
| |
| *phNewWaitObject = reinterpret_cast<PTP_WAIT>(iRet); |
| |
| return (iRet != 0); |
| } |
| |
| int32_t MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle) |
| { |
| int32_t iPid; |
| LARGE_INTEGER largeInteger; |
| |
| largeInteger.QuadPart = (int64_t)hWaitHandle; |
| |
| iPid = largeInteger.u.LowPart; |
| kill(iPid,SIGKILL); |
| return true; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : GMMDebugBreak |
| | Purpose : Fix compiling issue for Gmmlib on debug mode |
| | Arguments : N/A |
| | Returns : void |
| | Calls : N/A |
| | Callers : Several |
| \---------------------------------------------------------------------------*/ |
| void GMMDebugBreak(const char *file, const char *function,const int32_t line) |
| { |
| // Not required for media driver |
| return; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : GMMPrintMessage |
| | Purpose : Fix compiling issue for Gmmlib on debug mode |
| | Arguments : N/A |
| | Returns : void |
| | Calls : N/A |
| | Callers : Several |
| \---------------------------------------------------------------------------*/ |
| void GMMPrintMessage(int32_t debuglevel, const char *function, ...) |
| { |
| // Not Required for media driver |
| return; |
| } |
| |
| #else // ANDROID |
| MOS_STATUS MOS_UserFeatureNotifyChangeKeyValue( |
| void *UFKey, |
| int32_t bWatchSubtree, |
| HANDLE hEvent, |
| int32_t fAsynchronous) |
| { |
| MOS_UNUSED(UFKey); |
| MOS_UNUSED(bWatchSubtree); |
| MOS_UNUSED(hEvent); |
| MOS_UNUSED(fAsynchronous); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| HANDLE MOS_CreateEventEx( |
| void *lpEventAttributes, |
| char *lpName, |
| uint32_t dwFlags) |
| { |
| MOS_UNUSED(lpEventAttributes); |
| MOS_UNUSED(lpName); |
| MOS_UNUSED(dwFlags); |
| return (HANDLE)1; |
| } |
| |
| int32_t MOS_UserFeatureWaitForSingleObject( |
| PTP_WAIT* phNewWaitObject, |
| HANDLE hObject, |
| void *Callback, |
| void *Context) |
| { |
| MOS_UNUSED(phNewWaitObject); |
| MOS_UNUSED(hObject); |
| MOS_UNUSED(Callback); |
| MOS_UNUSED(Context); |
| return true; |
| } |
| |
| int32_t MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle) |
| { |
| MOS_UNUSED(hWaitHandle); |
| return true; |
| } |
| #endif // !ANDROID |
| |
| MOS_STATUS MOS_UserFeature_ParsePath( |
| PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface, |
| char * const pInputPath, |
| PMOS_USER_FEATURE_TYPE pUserFeatureType, |
| char **ppSubPath) |
| { |
| char *pValue; |
| MOS_USER_FEATURE_TYPE UserFeatureType; |
| size_t uUFKeyLen; |
| size_t uHKeyLen; |
| size_t uValLen; |
| size_t uSepLen; |
| MOS_UNUSED(pOsUserFeatureInterface); |
| |
| //------------------------------------------- |
| // the UserFeature interface is not currently an actual interface, just a collection |
| // of functions, so pOsUserFeatureInterface will always be nullptr until this changes |
| //MOS_OS_ASSERT(pOsUserFeatureInterface); |
| MOS_OS_ASSERT(pInputPath); |
| MOS_OS_ASSERT(strlen(pInputPath) > 0); |
| MOS_OS_ASSERT(pUserFeatureType); |
| MOS_OS_ASSERT(ppSubPath); |
| //------------------------------------------- |
| |
| pValue = nullptr; |
| |
| pValue = strstr(pInputPath, MOS_UF_SEPARATOR); |
| |
| if (!pValue) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid user feature key %s.", pInputPath); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| uUFKeyLen = strlen(pInputPath); |
| uValLen = strlen(pValue); |
| uSepLen = strlen(MOS_UF_SEPARATOR); |
| uHKeyLen = uUFKeyLen - uValLen; |
| |
| if (uHKeyLen == 0) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. Path separator in the begining.", pInputPath); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (uValLen <= uSepLen) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. No value after path separator.", pInputPath); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if ((uHKeyLen == strlen(MOS_UFKEY_EXT)) && |
| (strncmp(pInputPath, MOS_UFKEY_EXT, uHKeyLen) == 0)) |
| { |
| UserFeatureType = MOS_USER_FEATURE_TYPE_SYSTEM; |
| } |
| else if ((uHKeyLen == strlen(MOS_UFKEY_INT)) && |
| (strncmp(pInputPath, MOS_UFKEY_INT, uHKeyLen) == 0)) |
| { |
| UserFeatureType = MOS_USER_FEATURE_TYPE_USER; |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. Expected %s or %s.", pInputPath, MOS_UFKEY_EXT, MOS_UFKEY_INT); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| pValue = pValue + uSepLen; |
| |
| *pUserFeatureType = UserFeatureType; |
| *ppSubPath = pValue; |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| uint32_t MOS_GetLogicalCoreNumber() |
| { |
| return sysconf(_SC_NPROCESSORS_CONF); |
| } |
| |
| MOS_THREADHANDLE MOS_CreateThread( |
| void *ThreadFunction, |
| void *ThreadData) |
| { |
| MOS_THREADHANDLE Thread; |
| |
| if (0 != pthread_create(&Thread, nullptr, (void *(*)(void *))ThreadFunction, ThreadData)) |
| { |
| Thread = 0; |
| MOS_OS_ASSERTMESSAGE("Create thread failed."); |
| } |
| |
| return Thread; |
| } |
| |
| uint32_t MOS_GetThreadId( |
| MOS_THREADHANDLE hThread) |
| { |
| MOS_UNUSED(hThread); |
| return 0; |
| } |
| |
| uint32_t MOS_GetCurrentThreadId() |
| { |
| return (uint32_t)pthread_self(); |
| } |
| |
| MOS_STATUS MOS_WaitThread( |
| MOS_THREADHANDLE hThread) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (hThread == 0) |
| { |
| MOS_OS_ASSERTMESSAGE("MOS wait thread failed, invalid thread handle."); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| } |
| else if (0 != pthread_join(hThread, nullptr)) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to join thread."); |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| |
| return eStatus; |
| } |
| |
| PMOS_MUTEX MOS_CreateMutex() |
| { |
| PMOS_MUTEX pMutex; |
| |
| pMutex = (PMOS_MUTEX)MOS_AllocMemory(sizeof(*pMutex)); |
| if (pMutex != nullptr) |
| { |
| if (pthread_mutex_init(pMutex, nullptr)) |
| { |
| MOS_FreeMemory(pMutex); |
| pMutex = nullptr; |
| } |
| } |
| |
| return pMutex; |
| } |
| |
| MOS_STATUS MOS_DestroyMutex(PMOS_MUTEX pMutex) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (pMutex) |
| { |
| if (pthread_mutex_destroy(pMutex)) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| MOS_FreeMemory(pMutex); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS MOS_LockMutex(PMOS_MUTEX pMutex) |
| { |
| MOS_OS_CHK_NULL_RETURN(pMutex); |
| |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (pthread_mutex_lock(pMutex)) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS MOS_UnlockMutex(PMOS_MUTEX pMutex) |
| { |
| MOS_OS_CHK_NULL_RETURN(pMutex); |
| |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (pthread_mutex_unlock(pMutex)) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| |
| return eStatus; |
| } |
| |
| PMOS_SEMAPHORE MOS_CreateSemaphore( |
| uint32_t uiInitialCount, |
| uint32_t uiMaximumCount) |
| { |
| PMOS_SEMAPHORE pSemaphore = nullptr; |
| MOS_UNUSED(uiMaximumCount); |
| |
| pSemaphore = (PMOS_SEMAPHORE)MOS_AllocMemory(sizeof(*pSemaphore)); |
| if (!pSemaphore) |
| return nullptr; |
| if (sem_init(pSemaphore, 0, uiInitialCount)) |
| { |
| MOS_SafeFreeMemory(pSemaphore); |
| pSemaphore = nullptr; |
| } |
| |
| return pSemaphore; |
| } |
| |
| MOS_STATUS MOS_DestroySemaphore( |
| PMOS_SEMAPHORE pSemaphore) |
| { |
| MOS_SafeFreeMemory(pSemaphore); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MOS_WaitSemaphore( |
| PMOS_SEMAPHORE pSemaphore, |
| uint32_t uiMilliseconds) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (uiMilliseconds == INFINITE) |
| { |
| if (sem_wait(pSemaphore)) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| } |
| else |
| { |
| struct timespec time = { |
| (int32_t)uiMilliseconds / 1000000, |
| ((int32_t)uiMilliseconds % 1000000) * 1000}; |
| |
| if (sem_timedwait(pSemaphore, &time)) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS MOS_PostSemaphore( |
| PMOS_SEMAPHORE pSemaphore, |
| uint32_t uiPostCount) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (uiPostCount > 0) |
| { |
| while (uiPostCount--) |
| { |
| if (sem_post(pSemaphore)) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| break; |
| } |
| } |
| } |
| else |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| |
| return eStatus; |
| } |
| |
| uint32_t MOS_WaitForSingleObject( |
| void *pObject, |
| uint32_t uiMilliseconds) |
| { |
| uint32_t WaitSignal = 0; |
| MOS_UNUSED(pObject); |
| MOS_UNUSED(uiMilliseconds); |
| |
| return WaitSignal; |
| } |
| |
| uint32_t MOS_WaitForMultipleObjects( |
| uint32_t uiThreadCount, |
| void **ppObjects, |
| uint32_t bWaitAll, |
| uint32_t uiMilliseconds) |
| { |
| MOS_UNUSED(uiThreadCount); |
| MOS_UNUSED(ppObjects); |
| MOS_UNUSED(bWaitAll); |
| MOS_UNUSED(uiMilliseconds); |
| return 0; |
| } |
| |
| int32_t MOS_AtomicIncrement( |
| int32_t *pValue) |
| { |
| return __sync_fetch_and_add(pValue, 1); |
| } |
| |
| int32_t MOS_AtomicDecrement( |
| int32_t *pValue) |
| { |
| return __sync_fetch_and_sub(pValue, 1); |
| } |
| |
| VAStatus MOS_StatusToOsResult( |
| MOS_STATUS eStatus) |
| { |
| switch (eStatus) |
| { |
| case MOS_STATUS_SUCCESS: return VA_STATUS_SUCCESS; |
| case MOS_STATUS_NO_SPACE: return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| case MOS_STATUS_INVALID_PARAMETER: return VA_STATUS_ERROR_INVALID_PARAMETER; |
| case MOS_STATUS_INVALID_HANDLE: return VA_STATUS_ERROR_INVALID_BUFFER; |
| case MOS_STATUS_NULL_POINTER: return VA_STATUS_ERROR_INVALID_CONTEXT; |
| default: return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| MOS_STATUS OsResultToMOS_Status( |
| VAStatus eResult) |
| { |
| switch (eResult) |
| { |
| case VA_STATUS_SUCCESS: return MOS_STATUS_SUCCESS; |
| case VA_STATUS_ERROR_ALLOCATION_FAILED: return MOS_STATUS_NO_SPACE; |
| case VA_STATUS_ERROR_INVALID_PARAMETER: return MOS_STATUS_INVALID_PARAMETER; |
| case VA_STATUS_ERROR_INVALID_BUFFER: return MOS_STATUS_INVALID_HANDLE; |
| case VA_STATUS_ERROR_INVALID_CONTEXT: return MOS_STATUS_NULL_POINTER; |
| default: return MOS_STATUS_UNKNOWN; |
| } |
| |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| MOS_STATUS MOS_GetLocalTime( |
| struct tm* Tm) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| struct tm *pTm; |
| time_t lTime = time(nullptr); |
| pTm = localtime(&lTime); |
| if(pTm == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to get localtime."); |
| eStatus = MOS_STATUS_UNKNOWN; |
| return eStatus; |
| } |
| |
| eStatus = MOS_SecureMemcpy(Tm, sizeof(struct tm), pTm, sizeof(struct tm)); |
| return eStatus; |
| } |
| |
| void MOS_TraceEventInit() |
| { |
| return MosUtilities::MosTraceEventInit(); |
| } |
| |
| void MOS_TraceEventClose() |
| { |
| return MosUtilities::MosTraceEventClose(); |
| } |
| |
| void MOS_TraceSetupInfo(uint32_t DrvVer, uint32_t PlatFamily, uint32_t RenderFamily, uint32_t DeviceID) |
| { |
| // not implemented |
| } |
| |
| void MOS_TraceEvent( |
| uint16_t usId, |
| uint8_t ucType, |
| const void *pArg1, |
| uint32_t dwSize1, |
| const void *pArg2, |
| uint32_t dwSize2) |
| { |
| return MosUtilities::MosTraceEvent(usId, ucType, pArg1, dwSize1, pArg2, dwSize2); |
| } |
| |
| void MOS_TraceDataDump( |
| const char * pcName, |
| uint32_t flags, |
| const void * pBuf, |
| uint32_t dwSize) |
| { |
| // not implemented |
| } |
| |
| void MOS_TraceDataDictionary( |
| const char* pcName, |
| const void* pBuf, |
| uint32_t dwSize) |
| { |
| // not implemented |
| } |
| |
| |
| MOS_STATUS MOS_GfxInfoInit() |
| { |
| // not implemented |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| void MOS_GfxInfoClose() |
| { |
| // not implemented |
| } |
| |
| void MOS_GfxInfo_RTErr(uint8_t ver, |
| uint16_t compId, |
| uint16_t FtrId, |
| uint32_t ErrorCode, |
| uint8_t num_of_triples, |
| ...) |
| { |
| // not implemented |
| } |
| |
| void MOS_GfxInfo( |
| uint8_t ver, |
| uint16_t compId, |
| uint32_t tmtryID, |
| uint8_t num_of_triples, |
| ...) |
| { |
| // not implemented |
| } |