📄 util.cpp
字号:
// Security and/or authentication problems
hr = RIL_E_SECURITYFAILURE;
break;
case 0x6F:
// Internal SIM error, no further information given
hr = RIL_E_SIMFAILURE;
break;
case 0x67:
case 0x6B:
case 0x6D:
case 0x6E:
// I really shouldn't be getting these -- it means that one of the parameters I sent
// down to the SIM was invalid, but I already error checked for those -- so I guess
// it's best to assert and let a tester yell at me. In other words, FALL THROUGH!
default:
// I don't recognize this command!
hr = E_FAIL;
break;
}
return hr;
}
//
// Determines whether a file ID is an elementary SIM file or not
//
BOOL IsElementarySimFile(DWORD dwFileID)
{
FUNCTION_TRACE(IsElementarySimFile);
BOOL fRetVal = TRUE;
BYTE bIdentifier;
// Only the low WORD should be set
if (dwFileID & 0xffff0000)
{
fRetVal = FALSE;
}
else
{
bIdentifier = (BYTE) ((dwFileID & 0xff00) >> 8);
if ((bIdentifier != 0x2f) && (bIdentifier != 0x4f) && (bIdentifier != 0x6f))
{
// Bogus! It's not an elementary file
fRetVal = FALSE;
}
}
return fRetVal;
}
//
// Update the SIM state
//
void UpdateSIMState(DWORD dwSimState)
{
DWORD dwSimStatusChanged = 0;
// Set this in our global
switch(dwSimState)
{
case RIL_E_SIMPUKREQUIRED:
case RIL_E_PHFSIMPUKREQUIRED:
case RIL_E_NETWKPUKREQUIRED:
case RIL_E_SUBSETPUKREQUIRED:
case RIL_E_SVCPUKREQUIRED:
case RIL_E_CORPPUKREQUIRED:
case RIL_LOCKEDSTATE_SIM_PUK:
case RIL_LOCKEDSTATE_PH_FSIM_PUK:
case RIL_LOCKEDSTATE_PH_NET_PUK:
case RIL_LOCKEDSTATE_PH_NETSUB_PUK:
case RIL_LOCKEDSTATE_PH_SP_PUK:
case RIL_LOCKEDSTATE_PH_CORP_PUK:
dwSimStatusChanged = RIL_SIMSTATUSCHANGED_BLOCKED;
break;
case RIL_E_SIMWRONG:
dwSimStatusChanged = RIL_SIMSTATUSCHANGED_INVALID;
break;
case RIL_E_SIMNOTINSERTED:
dwSimStatusChanged = RIL_SIMSTATUSCHANGED_NO_SIM;
break;
case RIL_E_MEMORYFULL:
dwSimStatusChanged = RIL_SIMSTATUSCHANGED_FULL;
break;
case RIL_E_SIMPINREQUIRED:
case RIL_E_PHSIMPINREQUIRED:
case RIL_E_PHFSIMPINREQUIRED:
case RIL_E_NETWKPINREQUIRED:
case RIL_E_SUBSETPINREQUIRED:
case RIL_E_SVCPINREQUIRED:
case RIL_E_CORPPINREQUIRED:
case RIL_E_RADIOOFF:
case RIL_LOCKEDSTATE_SIM_PIN:
case RIL_LOCKEDSTATE_SIM_PIN2:
case RIL_LOCKEDSTATE_PH_SIM_PIN:
case RIL_LOCKEDSTATE_PH_FSIM_PIN:
case RIL_LOCKEDSTATE_PH_NET_PIN:
case RIL_LOCKEDSTATE_PH_NETSUB_PIN:
case RIL_LOCKEDSTATE_PH_SP_PIN:
case RIL_LOCKEDSTATE_PH_CORP_PIN:
case RIL_LOCKEDSTATE_READY:
// not puk'd, invalid, no sim, or full
dwSimStatusChanged = RIL_SIMSTATUSCHANGED_NONE;
break;
case RIL_E_SIMFAILURE:
case RIL_E_SIMBUSY:
default:
// who knows. could still be puk'd, invalid, no sim, or full
goto Exit;
break;
}
// Broadcast a SIM state change notification
CNotificationData* pnd = new CNotificationData;
if (pnd && !pnd->InitFromRealBlob(RIL_NOTIFY_SIMSTATUSCHANGED, (void*)&dwSimStatusChanged, sizeof(dwSimStatusChanged)))
{
delete pnd;
pnd = NULL;
}
else
{
// Add notification to command queue. pnd will be deleted after notification is sent.
QueueCmdIgnoreRsp(APIID_NONE, NULL, CMDOPT_INIT | CMDOPT_NOOP, g_TimeoutCmdInit, NULL, pnd, 0, 0, 0);
}
Exit:
return;
}
//
// StringFilterW
//
//
// Copies a string, filtering out unspecified characters.
//
// wszDest - [out] Pointer to buffer that receives filtered string.
// cchDest - [in] Size of the destination buffer in characters. This must be equal to the length
// of wszSrc plus 1 to account for the null termination.
// wszSrc - [in] Pointer to buffer containing the source string. Must be null terminated.
// wszFilter - [in] Pointer to a buffer containing a list of valid characters. In other words
// a list of characters that are acceptable to be copied to wszDest. If it is NULL
// or an empty list, then no filtering will occur and the string is copied directly.
// Must be null terminated, if the pointer is not NULL.
//
// Return Value:
// HRESULT
// S_OK - String copied and filtered.
// E_INVALIDARG - cchDest is either 0 or larger than STRSAFE_MAX_CCH
// Possible results from StringCchCopyW
//
HRESULT StringFilterW( __out_ecount( cchDest ) LPWSTR wszDest, size_t cchDest, const WCHAR *wszSrc, const WCHAR *wszFilter)
{
LPWSTR wszDestWalk = wszDest;
LPCWSTR wszSrcWalk = wszSrc;
size_t i = 0;
HRESULT hr = S_OK;
// Check incoming parameters
if (NULL == wszDest || NULL == wszSrc)
{
hr = E_INVALIDARG;
goto Exit;
}
if (0 == cchDest || cchDest > STRSAFE_MAX_CCH)
{
hr = E_INVALIDARG;
goto Exit;
}
// Only filter, if a filter exists otherwise just copy the string.
if (NULL != wszFilter && L'\0' != *wszFilter)
{
while( i < cchDest - 1 && *wszSrcWalk != '\0' )
{
if (wcschr(wszFilter, *wszSrcWalk))
{
*wszDestWalk++ = *wszSrcWalk;
}
wszSrcWalk++;
i++;
}
*wszDestWalk = L'\0';
}
else
{
hr = StringCchCopyW(wszDest, cchDest, wszSrc);
}
Exit:
return hr;
}
#ifdef GPRS_CONTEXT_CACHING
char g_szGPRSContextCmdCache[MAX_PATH];
void UpdateGPRSContextCommandCache( LPCSTR szCmd )
{
strncpyz(g_szGPRSContextCmdCache, szCmd, ARRAY_LENGTH(g_szGPRSContextCmdCache));
return;
}
void ClearGPRSContextCommandCache()
{
g_szGPRSContextCmdCache[0] = '\0';
}
bool IsGPRSContextCommandCached( LPCSTR szCmd )
{
return (0 == strncmp(szCmd, g_szGPRSContextCmdCache, ARRAY_LENGTH(g_szGPRSContextCmdCache)));
}
#endif // GPRS_CONTEXT_CACHING
#ifdef RIL_RADIO_RESILIENCE
BYTE g_PINCRYPTBUFFER[256];
DWORD g_cbPINBytes=0;
void SavePINSecure(LPCSTR szNewPIN)
{
DATA_BLOB inBlob;
inBlob.pbData = (BYTE*)szNewPIN;
inBlob.cbData = strlen(szNewPIN) + 1;
DATA_BLOB outBlob;
outBlob.cbData = sizeof(g_PINCRYPTBUFFER);
outBlob.pbData = g_PINCRYPTBUFFER;
if ((szNewPIN == NULL) || (*szNewPIN == '\0') || (CryptProtectData(&inBlob, NULL, NULL, NULL, NULL, CRYPTPROTECT_SYSTEM, &outBlob) == FALSE))
{
g_cbPINBytes = 0;
}
else
{
g_cbPINBytes = outBlob.cbData;
}
}
BOOL FetchPINSecure(LPSTR szPinBuffer, DWORD cbBufferSIze)
{
DATA_BLOB inBlob;
inBlob.cbData = g_cbPINBytes;
inBlob.pbData = g_PINCRYPTBUFFER;
DATA_BLOB outBlob;
outBlob.cbData = cbBufferSIze;
outBlob.pbData = (BYTE *)szPinBuffer;
BOOL fReturn = FALSE;
if ((g_cbPINBytes == 0) || (CryptUnprotectData(&inBlob, NULL, NULL, NULL, NULL, CRYPTPROTECT_SYSTEM, &outBlob) == FALSE))
{
szPinBuffer[0] = '\0';
}
else
{
fReturn = TRUE;
}
return fReturn;
}
#endif // RIL_RADIO_RESILIENCE
//
// Creates a cmd string that includes a byte array (in HEX representation)
// NOTE: the caller is responsible for releasing memory allocated for rszCmd
//
BOOL ComposeCmdWithByteArray(const LPCSTR szPrefix, const BYTE* const pbBytes, const UINT cbBytes,
const LPCSTR szPostfix, LPSTR& rszCmd)
{
FUNCTION_TRACE(ComposeCmdWithByteArray);
DEBUGCHK(NULL != szPrefix);
DEBUGCHK(NULL != szPostfix);
UINT i;
UINT cbCmd;
LPSTR szWalk;
const BYTE *pbBytesWalk;
BOOL fRet = FALSE;
rszCmd = 0;
// Allocate the command string
cbCmd = MAX_PATH + strlen(szPrefix) + strlen(szPostfix) + cbBytes * 2;
rszCmd = new char[cbCmd];
if (!rszCmd)
{
goto Error;
}
szWalk = rszCmd;
// Add "<prefix>"
(void)strncpyz(szWalk, szPrefix, cbCmd - (szWalk - rszCmd));
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
// Add the byte array coverted to HEX representation, if provided
if (cbBytes)
{
if (g_rppPDDParams->fByteArrayIsQuoted) {
*szWalk++ = '\"';
}
pbBytesWalk = (BYTE*)pbBytes;
for (i = 0; i < cbBytes; i++)
{
DEBUGCHK(cbCmd >= (UINT)(szWalk - rszCmd + 2));
*szWalk++ = SemiByteToChar(*pbBytesWalk, TRUE);
*szWalk++ = SemiByteToChar(*pbBytesWalk++, FALSE);
}
if (g_rppPDDParams->fByteArrayIsQuoted) {
*szWalk++ = '\"';
}
}
// Add "<postfix>"
(void)strncpyz(szWalk, szPostfix, cbCmd - (szWalk - rszCmd)); // NO_TYPO: 30
fRet = TRUE;
Error:
if (!fRet)
{
delete[] rszCmd;
}
return fRet;
}
//
// Alternate line support
//
// The following function helps us separate the implementation of
// alternate line support without cluttering the original
// source code too much.
//
#define UNUSED_PARAM(x) x
//
// Fills the command buffer with AT plus any required modifier to specify
// the line on which the command should apply.
//
// Returns a pointer to where the rest of the command can be written
// to the buffer.
//
char * BeginLineSpecificCommand( __out_ecount( cchSize ) char *szCmdDst, UINT cchSize, DWORD dwAddressId)
{
UNUSED_PARAM(dwAddressId);
(void)strncpyz(szCmdDst, "AT", cchSize);
return strchr(szCmdDst, '\0'); // NO_TYPO: 27
}
//
// (Re)Allocates storage for data elements
// prgrData - Pointer to current buffer (buffer must be NULL if (0 == nAllocated))
// stSize - Size (in bytes) of the data elements in the buffer
// nUsed - Number of valid data elements in the buffer
// pnAllocated - Total number of data elements in the buffer
// nGrowSize - Number of elements by which to increase the size of the buffer
//
BOOL AllocateOrReallocateStorage(BYTE** const prgrData, const size_t stSize, const UINT nUsed, UINT* const pnAllocated, const UINT nGrowSize)
{
FUNCTION_TRACE(AllocateOrReallocateStorage);
DEBUGCHK(prgrData && pnAllocated && (*prgrData || (0 == *pnAllocated)));
BOOL fSuccess = FALSE;
*pnAllocated += nGrowSize;
size_t stAllocateBytes;
if ( !safeIntUMul( *pnAllocated, stSize, &stAllocateBytes ) )
{
ASSERT( FALSE );
goto err_label;
}
BYTE* const prbTemp = (BYTE*)AllocBlob(stAllocateBytes);
if (prbTemp)
{
const size_t stUsedBytes = nUsed * stSize;
memcpy(prbTemp, *prgrData, stUsedBytes);
// The following line seems like a good idea, but may waste resources
// 0-initializing memory that is never used.
// memset(prbTemp + stUsedBytes, 0x00, stAllocateBytes - stUsedBytes);
FreeBlob(*prgrData);
*prgrData = prbTemp;
fSuccess = TRUE;
}
else
{
*pnAllocated -= nGrowSize;
}
err_label:
return fSuccess;
}
//
// Buffer ctor
//
CBuffer::CBuffer()
: m_szData(NULL),
m_cbLength(0),
m_cbAlloc(0)
{
// FUNCTION_TRACE(CBuffer::CBuffer);
}
//
// Buffer dtor
//
CBuffer::~CBuffer()
{
// FUNCTION_TRACE(CBuffer::~CBuffer);
delete[] m_szData;
}
__inline BOOL safeIntUAddThree(unsigned int addend1, unsigned int addend2, unsigned int addend3, unsigned int *pSum)
{
BOOL ReturnValue = FALSE;
if ( pSum )
{
if ( TRUE == safeIntUAdd(addend1, addend2, pSum))
{
if ( TRUE == safeIntUAdd( *pSum, addend3, pSum ) )
{
ReturnValue = TRUE;
}
}
}
return ReturnValue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -