📄 util.cpp
字号:
}
rcbUsed = pchOut - sOut;
fRet = TRUE;
}
Error:
delete[] sOutTemp;
return fRet;
}
//
// Convert a specified string to Unicode
//
BOOL ConvertToUnicode(const ENCODING_TYPE enc, const LPCSTR sIn, const UINT cbIn, __out_ecount( cchOut ) const LPWSTR wsOut, const UINT cchOut,
UINT& rcchUsed)
{
FUNCTION_TRACE(ConvertToUnicode);
LPCSTR pchInEnd;
LPCSTR pchIn;
LPCWSTR pwchOutEnd;
LPWSTR pwchOut;
LPSTR sInTemp = NULL;
UINT cbUsedTemp;
char ch7Bit;
UINT nBits;
BYTE bValue;
BOOL fRet = FALSE;
rcchUsed = 0;
if (ENCODING_GSMDEFAULT == enc)
{
pchInEnd = sIn + cbIn;
pwchOutEnd = wsOut + cchOut;
pchIn = sIn;
pwchOut = wsOut;
ch7Bit = 0x00;
nBits = 0;
while (pchIn < pchInEnd && pwchOut < pwchOutEnd)
{
bValue = (BYTE)*pchIn++;
ch7Bit += (bValue << nBits) & 0x7f;
if ( ch7Bit >= sizeof(g_rgwchGSMToUnicode) / sizeof(*g_rgwchGSMToUnicode) )
{
ASSERT( FALSE );
goto Error;
}
*pwchOut++ = g_rgwchGSMToUnicode[ch7Bit];
ch7Bit = (bValue >> (7 - nBits)) & 0x7f;
nBits = (nBits + 1) % 7;
if (!nBits && pwchOut < pwchOutEnd)
{
*pwchOut++ = g_rgwchGSMToUnicode[ch7Bit];
ch7Bit = 0x00;
}
}
rcchUsed = pwchOut - wsOut;
fRet = TRUE;
}
else if (ENCODING_GSMDEFAULT_UNPACKED == enc)
{
DWORD dwCharCount = 0;
while ((dwCharCount < cbIn) && (dwCharCount < cchOut))
{
wsOut[dwCharCount] = g_rgwchGSMToUnicode[sIn[dwCharCount]];
dwCharCount++;
}
rcchUsed = dwCharCount;
fRet = TRUE;
}
else if ((ENCODING_GSMDEFAULT_HEX == enc) || (ENCODING_GSMDEFAULT_HEX_UNPACKED == enc))
{
ENCODING_TYPE etSubEncoding;
if (ENCODING_GSMDEFAULT_HEX_UNPACKED == enc)
{
etSubEncoding = ENCODING_GSMDEFAULT_UNPACKED;
}
else
{
etSubEncoding = ENCODING_GSMDEFAULT;
}
sInTemp = new char[cbIn / 2 + 1];
if (!sInTemp)
{
goto Error;
}
if (!GSMHexToGSM(sIn, cbIn, sInTemp, cbIn / 2 + 1, cbUsedTemp))
{
goto Error;
}
if (!ConvertToUnicode(etSubEncoding, sInTemp, cbUsedTemp, wsOut, cchOut, rcchUsed))
{
goto Error;
}
fRet = TRUE;
}
else if (ENCODING_GSMDEFAULT_UNICODE == enc)
{
pchIn = sIn;
pchInEnd = sIn + cbIn;
pwchOut = wsOut;
pwchOutEnd = wsOut + cchOut;
while ((pchIn+3) < pchInEnd && pwchOut < pwchOutEnd)
{
int i1 = SemiByteCharsToByte( pchIn[0], pchIn[1] );
int i0 = SemiByteCharsToByte( pchIn[2], pchIn[3] );
*pwchOut = (WCHAR)( ( i1 << 8 ) | i0 );
pchIn += 4;
pwchOut++;
}
rcchUsed = pwchOut - wsOut;
fRet = TRUE;
}
else if (ENCODING_GSMDEFAULT_UTF8 == enc)
{
pchIn = sIn;
pchInEnd = sIn + cbIn;
pwchOut = wsOut;
pwchOutEnd = wsOut + cchOut;
while ((pchIn < pchInEnd) && (pwchOut < pwchOutEnd))
{
BYTE ch = *pchIn++;
WCHAR wch;
if (0 == (ch & 0x80))
{ // 7 bits, 1 byte
wch = (WCHAR) ch;
}
else if (0xC0 == (ch & 0xE0))
{ // 11 bits, 2 bytes
if (pchIn + 1 > pchInEnd)
goto Error;
BYTE ch2 = *pchIn++;
if (0x80 != (ch2 & 0xC0))
goto Error;
wch = ((ch & 0x1F) << 6) | (ch2 & 0x3F);
}
else if (0xE0 == (ch & 0xF0))
{ // 16 bits, 3 bytes
if (pchIn + 2 > pchInEnd)
goto Error;
BYTE ch2 = *pchIn++;
BYTE ch3 = *pchIn++;
if (0x80 != (ch2 & 0xC0) || 0x80 != (ch3 & 0xC0))
goto Error;
wch = ((ch & 0x0F) << 12) | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F);
}
else
goto Error;
*pwchOut++ = wch;
}
rcchUsed = pwchOut - wsOut;
fRet = TRUE;
}
Error:
delete[] sInTemp;
return fRet;
}
//
// Convert a RILADDRESS structure to AT address string
//
HRESULT RILAddressToString(const RILADDRESS& rraAddress, __out_bcount( cbOut ) const LPSTR szOut, const UINT cbOut, BYTE& rbTypeOfAddress, ENCODING_TYPE etEncoding)
{
FUNCTION_TRACE(RILAddressToString);
LPWSTR wszFilteredAddr[MAXLENGTH_ADDRESS];
UINT cbUsed;
HRESULT hr = E_INVALIDARG;
// Must have a type and an address specified
if (!(rraAddress.dwParams & RIL_PARAM_A_TYPE) || !(rraAddress.dwParams & RIL_PARAM_A_ADDRESS))
{
goto Error;
}
if (rraAddress.dwType >= NUM_ADDRTYPES)
{
goto Error;
}
// Only allow characters in the set specified by GSM 07.07 section 6.2
if (FAILED(StringFilterW((LPWSTR)wszFilteredAddr,
ARRAY_LENGTH(wszFilteredAddr),
(LPWSTR)rraAddress.wszAddress,
L"1234567890*#+ABCD,TP!W@")))
{
goto Error;
}
if ((RIL_ADDRTYPE_ALPHANUM == rraAddress.dwType) ||
(ENCODING_GSMDEFAULT_HEX_UNPACKED == etEncoding) ||
(ENCODING_GSMDEFAULT_UNICODE == etEncoding) ||
(ENCODING_GSMDEFAULT_UTF8 == etEncoding))
{
// Need to convert to default GSM alphabet
if (!ConvertFromUnicode(etEncoding,
(LPWSTR)wszFilteredAddr,
wcslen((LPWSTR)wszFilteredAddr),
szOut, cbOut - 1, cbUsed))
{
hr = E_FAIL;
goto Error;
}
}
else
{
// Just copy the number directly
#pragma prefast( suppress: 5464, "PREfast noise: No change necessary." )
cbUsed = min(cbOut - 1, wcslen((LPWSTR)wszFilteredAddr));
StringCbCopyNA( szOut, cbOut, USAsciiString((LPWSTR)wszFilteredAddr), cbUsed );
}
szOut[cbUsed] = '\0';
// Add address type to Type-of-Address byte (high bit is always set)
rbTypeOfAddress = 0x80 | (g_rgbAddrTypes[rraAddress.dwType] << 4);
if (RIL_ADDRTYPE_UNKNOWN == rraAddress.dwType ||
RIL_ADDRTYPE_INTERNATIONAL == rraAddress.dwType ||
RIL_ADDRTYPE_NATIONAL == rraAddress.dwType)
{
// Must have a numbering plan specified for these address types
if (!(rraAddress.dwParams & RIL_PARAM_A_NUMPLAN))
{
goto Error;
}
if (rraAddress.dwNumPlan >= NUM_NUMPLANS)
{
goto Error;
}
// Add numbering plan to the Type-of-addres byte
rbTypeOfAddress |= g_rgbNumPlans[rraAddress.dwNumPlan];
}
else
{
goto Error;
}
hr=S_OK;
Error:
return hr;
}
//
// Convert an AT address string to RILADDRESS structure
//
BOOL StringToRILAddress(const LPCSTR szAddress, const BYTE bTypeOfAddress, RILADDRESS& rraAddress, ENCODING_TYPE etEncoding)
{
FUNCTION_TRACE(StringToRILAddress);
BYTE bType = (bTypeOfAddress & 0x70) >> 4;
BYTE bNumPlan = bTypeOfAddress & 0x0f;
UINT cchUsed;
UINT i;
BOOL fRet = FALSE;
rraAddress.cbSize = sizeof(RILADDRESS);
rraAddress.dwParams = 0;
// Determine the type
for (i = 0; i < NUM_ADDRTYPES; i++)
{
if (g_rgbAddrTypes[i] == bType)
{
rraAddress.dwType = i;
break;
}
}
if (i < NUM_ADDRTYPES)
{
rraAddress.dwParams |= RIL_PARAM_A_TYPE;
}
if (RIL_ADDRTYPE_UNKNOWN == rraAddress.dwType ||
RIL_ADDRTYPE_INTERNATIONAL == rraAddress.dwType ||
RIL_ADDRTYPE_NATIONAL == rraAddress.dwType)
{
// Determine the numbering plan
for (i = 0; i < NUM_NUMPLANS; i++)
{
if (g_rgbNumPlans[i] == bNumPlan)
{
rraAddress.dwNumPlan = i;
break;
}
}
if (i < NUM_NUMPLANS)
{
rraAddress.dwParams |= RIL_PARAM_A_NUMPLAN;
}
}
// Convert the address string to Unicode
if ((RIL_ADDRTYPE_ALPHANUM == rraAddress.dwType) ||
(ENCODING_GSMDEFAULT_HEX_UNPACKED == etEncoding) ||
(ENCODING_GSMDEFAULT_UNICODE == etEncoding) ||
(ENCODING_GSMDEFAULT_UTF8 == etEncoding))
{
if (!ConvertToUnicode(etEncoding, szAddress, strlen(szAddress), rraAddress.wszAddress,
MAXLENGTH_ADDRESS - 1, cchUsed))
{
goto Error;
}
if (rraAddress.wszAddress[0] == L'+')
{
memmove(rraAddress.wszAddress, rraAddress.wszAddress+1, (--cchUsed) * sizeof(TCHAR));
rraAddress.dwType = RIL_ADDRTYPE_INTERNATIONAL;
rraAddress.dwNumPlan = RIL_NUMPLAN_TELEPHONE;
rraAddress.dwParams |= RIL_PARAM_A_NUMPLAN;
}
}
else
{
LPCSTR sz = szAddress;
// In case we have a '+' in a number that we already
// know is an INTERNATIONAL type, then remove it.
if (RIL_ADDRTYPE_INTERNATIONAL == rraAddress.dwType &&
'+' == *sz)
{
sz++;
}
// Just copy the number directly
#pragma prefast( suppress: 5464, "PREfast noise: No change necessary." )
cchUsed = min(MAXLENGTH_ADDRESS - 1, strlen(sz));
StringCchCopyNW( rraAddress.wszAddress, sizeof(rraAddress.wszAddress) / sizeof(*(rraAddress.wszAddress)), WideString(sz), cchUsed );
}
rraAddress.wszAddress[cchUsed] = L'\0';
rraAddress.dwParams |= RIL_PARAM_A_ADDRESS;
fRet = TRUE;
Error:
return fRet;
}
//
// Convert a RILSUBADDRESS structure to AT sub-address string
//
HRESULT RILSubAddressToString(const RILSUBADDRESS& rrsaSubAddress, __out_ecount( cchOut ) const LPSTR szOut, const UINT cchOut, BYTE& rbType)
{
FUNCTION_TRACE(RILSubAddressToString);
HRESULT hr = S_OK;
// Must have a type and a sub-address specified
if (!(rrsaSubAddress.dwParams & RIL_PARAM_SA_TYPE) || !(rrsaSubAddress.dwParams & RIL_PARAM_SA_SUBADDRESS))
{
hr = E_INVALIDARG;
goto Error;
}
// Copy the subaddress data out of the structure.
(void)strncpyz(szOut, USAsciiString(rrsaSubAddress.wszSubAddress), cchOut);
DEBUGCHK(0x100 > rrsaSubAddress.dwType);
rbType = (BYTE)rrsaSubAddress.dwType;
Error:
return hr;
}
//
// Convert an AT sub-address string to RILSUBADDRESS structure
//
BOOL StringToRILSubAddress(const LPCSTR szSubAddress, const BYTE bType, RILSUBADDRESS& rrsaSubAddress)
{
FUNCTION_TRACE(StringToRILSubAddress);
rrsaSubAddress.cbSize = sizeof(RILSUBADDRESS);
rrsaSubAddress.dwParams = 0;
// Copy the subaddress data into the structure.
(void)wcsncpyz(rrsaSubAddress.wszSubAddress, WideString(szSubAddress), MAXLENGTH_SUBADDR);
rrsaSubAddress.dwParams |= RIL_PARAM_SA_SUBADDRESS;
rrsaSubAddress.dwType = bType;
rrsaSubAddress.dwParams |= RIL_PARAM_SA_TYPE;
return TRUE;
}
//
// Determine the error from a SendRestrictedSimCmd based on status word 1 and status word 2
//
HRESULT DetermineSimResponseError(DWORD dwSW1, DWORD dwSW2)
{
FUNCTION_TRACE(DetermineSimResponseError);
HRESULT hr;
switch (dwSW1)
{
case 0x90:
case 0x91:
case 0x9F:
// This is good
hr = S_OK;
break;
case 0x92:
if ((dwSW2 & 0xf0) == 0x00)
{
// The command completed OK, but the SIM had to retry the command internally
// a few times, but what do I care if the SIM is whining?
hr = S_OK;
}
else
{
// Memory problem
hr = RIL_E_MEMORYFULL;
}
break;
case 0x94:
// SW2 = 0x00, 0x02, or 0x08
// These all means that there was a problem with the file (e.g. invalid address, or
// they specified the type of file incorrectly)
hr = RIL_E_INVALIDINDEX;
break;
case 0x98:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -