📄 dialengine.cpp
字号:
}
*pRestrictedServices = 0;
//caller can specify -1 for the dial string length if the string is null-terminated
//and wants this API to calculate the length for them
if (DialStringLength == -1)
{
DialStringLength = wcslen(pDialString);
}
if (DialStringLength <= 0)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
hr = FindMatch(pDialString, DialStringLength, &pDialingRule);
if (FAILED(hr))
{
// No rule defined for this number
return hr;
}
*pRestrictedServices = (pDialingRule->m_Flags & DRF_RESTRICT_OPTION_ALL);
return S_OK;
}
/*------------------------------------------------------------------------------
DialEngine_t::LoadCustomDialPlan
Loads custom dial plan from the registry
Parameters:
: OUT - BSTR* - The XML string for custom dial plan
Returns:
- (HRESULT) indicating success or failure
------------------------------------------------------------------------------*/
inline
HRESULT
DialEngine_t::LoadCustomDialPlan(
BSTR *pDialPlanXML
)
{
ASSERT(pDialPlanXML != NULL);
return (GetApp()->GetSettings()).GetDialPlan(pDialPlanXML);
}
/*------------------------------------------------------------------------------
DialEngine_t::LoadDefaultDialPlan
Loads default dial plan from ROM
Parameters:
: OUT - BSTR* - The XML string for default dial plan
Returns:
- (HRESULT) indicating success or failure
------------------------------------------------------------------------------*/
HRESULT
DialEngine_t::LoadDefaultDialPlan(
BSTR *pDialPlanXML
)
{
ce::auto_bstr CopyOfDialPlanURL;
ASSERT(pDialPlanXML);
*pDialPlanXML = NULL;
CopyOfDialPlanURL = SysAllocString(sc_DefaultDialPlan);
if (CopyOfDialPlanURL == NULL)
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to allocate URL for default dial plan"));
return E_OUTOFMEMORY;
}
*pDialPlanXML = CopyOfDialPlanURL.release();
return S_OK;
}
/*------------------------------------------------------------------------------
DialEngine_t::OnSettingsChange
implements the ISettingChangeHandler_t::OnSettingsChange
Parameters:
: IN - DWORD - DialPlan related setting flag
Returns:
- (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT
DialEngine_t::OnSettingsChange(
DWORD SettingFlags
)
{
if (SettingFlags & SEF_VOIP_DIALPLAN)
{
return UpdateDialPlan();
}
ASSERT(FALSE);
return E_NOTIMPL;
}
/*------------------------------------------------------------------------------
DialEngine_t::UpdateRegularExpressions
Updates regular expresions in the registry (when dial plan is updated)
Parameters:
: IN - RegistryRegexAPI_e - Name of the regex-based API
------------------------------------------------------------------------------*/
void
DialEngine_t::UpdateRegularExpressions(
RegistryRegexAPI_e RegexAPI
)
{
LONG Result;
HKEY Key;
const WCHAR* pKeyPath;
WCHAR Buffer[sc_MaxRegexNameBuffer]; // used for subkey's name
DWORD BufferSize;
DWORD Type;
DWORD MustSetFlags;
DWORD MustNoSetFlags;
DWORD Index;
DWORD MaximumIndexUsed;
DialingRuleQueue::iterator Item;
ce::list<int> SubKeysToDelete;
bool NeedToRemoveOldSubKeys = true;
switch (RegexAPI)
{
case RegexVoIPPhoneNumber:
// Update VoIPPhoneNumber regular expressions stored in the registry
MustSetFlags = DRF_RESTRICT_OPTION_CELL;
MustNoSetFlags = DRF_RESTRICT_OPTION_VOIP;
pKeyPath = REG_szSecurityVoIPPhoneSetting_RegexVoIPPhoneNumberKey;
break;
case RegexSMSBlockedNumber:
// Update SMSBlockedNumber regular expressions stored in the registry
MustSetFlags = DRF_RESTRICT_OPTION_SMS;
MustNoSetFlags = 0;
pKeyPath = REG_szSecurityVoIPPhoneSetting_RegexSMSBlockedNumberKey;
break;
default:
return;
}
Result = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
pKeyPath,
0,
NULL,
0,
0,
NULL,
&Key,
&Type
);
if (ERROR_SUCCESS != Result)
{
return;
}
// No need to remove previous subkeys if the Key was just created
NeedToRemoveOldSubKeys = (Type != REG_CREATED_NEW_KEY);
// Go through all dialing rules and update subkeys first
Index = 0;
for (Item = m_pDialingRules->begin(); Item != m_pDialingRules->end(); Item++)
{
if (((*Item)->m_Flags & MustSetFlags) && !((*Item)->m_Flags & MustNoSetFlags))
{
HKEY SubKey;
// Start with DialPlan001
Index++;
StringCchPrintf(
Buffer,
_countof(Buffer),
L"%s%0*d",
sc_RegexNamePrefix,
sc_MinNumberOfDigits,
Index
);
Result = RegCreateKeyEx(
Key,
Buffer,
0,
NULL,
0,
0,
NULL,
&SubKey,
&Type
);
if (ERROR_SUCCESS == Result)
{
// size in bytes
BufferSize = SysStringByteLen((*Item)->m_RegexString)+ sizeof(WCHAR);
Result = RegSetValueEx(
SubKey,
REG_szSecurityVoIPPhoneSetting_Regex,
0,
REG_SZ,
(const BYTE*)(*Item)->m_RegexString,
BufferSize
);
ASSERT(ERROR_SUCCESS == Result);
RegCloseKey(SubKey);
}
}
}
MaximumIndexUsed = Index;
if (!NeedToRemoveOldSubKeys)
{
goto exit;
}
// Now detect unnecesary subkeys (old)
Index = 0;
do
{
// size in characters
BufferSize = _countof(Buffer);
Result = RegEnumKeyEx(
Key,
Index,
Buffer,
&BufferSize,
NULL,
NULL,
NULL,
NULL
);
Index++;
if (ERROR_SUCCESS != Result)
{
if (ERROR_MORE_DATA == Result)
{
// Not one of our subkeys, continue looking
continue;
}
ASSERT((Index == 1) || (ERROR_NO_MORE_ITEMS == Result));
break;
}
if (0 != wcsncmp(Buffer, sc_RegexNamePrefix, _countof(sc_RegexNamePrefix)-1))
{
// Not one of our subkeys, continue looking
continue;
}
// We have found potential candidate to delete
// Make sure it is not one of the previously updated subkeys
if (sc_MaxRegexNameBuffer == wcslen(Buffer) + 1)
{
WCHAR* pEnd;
DWORD SubKeyIndex = wcstoul(&Buffer[_countof(sc_RegexNamePrefix)-1], &pEnd, 10);
if ((*pEnd == L'\0') && (SubKeyIndex > 0))
{
if (SubKeyIndex <= MaximumIndexUsed)
{
continue;
}
else
{
SubKeysToDelete.push_back(SubKeyIndex);
}
}
}
} while(Index < MAXDWORD);
// Now delete the subkeys
while (SubKeysToDelete.size() > 0)
{
StringCchPrintf(
Buffer,
_countof(Buffer),
L"%s%0*d",
sc_RegexNamePrefix,
sc_MinNumberOfDigits,
SubKeysToDelete.front()
);
RegDeleteKey(Key, Buffer);
SubKeysToDelete.pop_front();
}
exit:
if (Key)
{
RegCloseKey(Key);
}
}
/*------------------------------------------------------------------------------
DialEngine_t::IsPhoneNumberReadyForAutoDial
Determine whether this phone number is ready for auto dial
Parameters:
: IN - const WCHAR* null terminated dialing string
------------------------------------------------------------------------------*/
bool
DialEngine_t::IsPhoneNumberReadyForAutoDial(
const WCHAR* pDialString
)
{
if (pDialString == NULL ||
pDialString[0] == L'\0')
{
return false;
}
unsigned int Length = 0;
for (const WCHAR* pIndex = pDialString; *pIndex != L'\0'; pIndex ++)
{
if (*pIndex < L'0' || *pIndex > L'9')
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Not all chars are numeric, can not auto-dial!"));
return false;
}
Length++;
}
if (m_pAutoDialRules == NULL ||
m_pAutoDialRules->empty())
{
return false;
}
AutoDialRuleQueue::iterator Item;
// Go through all auto dial rules until first match to prefix is found
// then compare against the length of the dialing string
for (Item = m_pAutoDialRules->begin(); Item != m_pAutoDialRules->end(); Item++)
{
if (wcsncmp(pDialString, (*Item)->m_Prefix, (*Item)->m_PrefixLength) == 0)
{
return (Length == (*Item)->m_TotalLength);
}
}
return false;
}
/*------------------------------------------------------------------------------
DialEngine_t::ReleaseCachedResources
Release Cached resources.
Currently we only flush out those 'pre-compiled' regular expressions associated with each dialing rule
------------------------------------------------------------------------------*/
HRESULT
DialEngine_t::ReleaseCachedResources(
void
)
{
if (m_pDialingRules->empty())
{
return S_FALSE;
}
// Go through all dialing rules and flush all the pre-compiled regular expressions to release some heap memory
for (DialingRuleQueue::iterator Item = m_pDialingRules->begin(); Item != m_pDialingRules->end(); Item++)
{
(*Item)->FlushCompiledRegex();
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -