⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 settings.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                WM_CHANGE_PHONE_SETTINGS, 
                Index
                ); 
        
        if (FAILED(hr))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Could not register callback for phone related setting notifications"));            
            return hr;             
        }        
    }

    return S_OK; 
    
}

/*------------------------------------------------------------------------------
    Settings_t::s_ListenerWindowProc

    handles messages sent to our Listener window
------------------------------------------------------------------------------*/
LRESULT
Settings_t::s_ListenerWindowProc(
    HWND hwnd,
    UINT Message,
    WPARAM wParam,
    LPARAM lParam
    )
{
    Settings_t* pSettings = NULL;

    if (Message == WM_CREATE)
    {
        //On WM_CREATE we pack the settings_t object into the createstruct
        //now we need to extract the object and store it into USERDATA section of the window
        CREATESTRUCT*   pCreateStruct = reinterpret_cast<CREATESTRUCT*>(lParam); 
        if (!pCreateStruct)
        {
            ASSERT(FALSE); 
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Create Struct is empty -- can not create this window")); 
            return -1; 
        }

        pSettings = reinterpret_cast<Settings_t*>(pCreateStruct->lpCreateParams); 
        if (pSettings == NULL)
        {
            ASSERT(FALSE); 
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"No canvas object in the create struct - cannot create this window"));
            return -1; 
        }
        
        SetWindowLong(
            hwnd, 
            GWL_USERDATA, 
            reinterpret_cast<LONG>(pSettings)
            );
        
    }
    else
    {
        pSettings = reinterpret_cast<Settings_t*>(GetWindowLong(hwnd, GWL_USERDATA)); 
    }

    if (pSettings == NULL)
    {
        return DefWindowProc(hwnd, Message, wParam, lParam); 
    }

    return pSettings->ListenerWindowProc(hwnd, Message, wParam, lParam); 

}

LRESULT 
Settings_t::ListenerWindowProc(
    HWND hwnd,
    UINT Message,
    WPARAM wParam,
    LPARAM lParam
    )
{
    DWORD   StatStoreSettingChange = SEF_NONE;
    
    switch(Message)
    {
        case WM_CHANGE_PROVISION_SETTINGS:
            StatStoreSettingChange |= GetUpdatedVoIPSettingFlags();
            break; 

        case WM_CHANGE_PHONE_SETTINGS: 
            s_PhoneSettings[(DWORD)lParam]->Update(); 
            break;                 

        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }

    if (m_PendingSettingUpdateFlags != SEF_NONE)
    {
        //add the pending settings to the updated settings
        StatStoreSettingChange |= m_PendingSettingUpdateFlags;

        //reset the pending settins to 0
        m_PendingSettingUpdateFlags = SEF_NONE;
    }

    NotifySettingHandlers(StatStoreSettingChange);

    return 0;
}

/*------------------------------------------------------------------------------
    OnTimerExpires

    implements the ITimerHandler_t::OnTimerExpires
    Parameters:
        TimerIdentifier:    [IN] the timer identifier

    Returns: none
------------------------------------------------------------------------------*/
void
Settings_t::OnTimerExpires(
    UINT TimerIdentifier
    )
{
    if (TimerIdentifier == m_RetryTimerIdentifier)
    {
        //kill the timer first
        (GetApp()->GetTimers()).RemoveTimer(m_RetryTimerIdentifier); 

        //get the pending setting flags
        DWORD UpdatedSettingFlags = m_PendingSettingUpdateFlags;

        //reset the pending setting flags
        m_PendingSettingUpdateFlags = SEF_NONE;

        //re-try to notify the setting handlers for the pending setting changes
        NotifySettingHandlers(UpdatedSettingFlags);

    }

    return;
}

/*------------------------------------------------------------------------------
    NotifySettingHandlers

    Dispatch the updated setting flags to corresponding setting handler to process

    Parameters:
        UpdatedSettingFlags: [IN] the updated setting flags that need to be dispatched.

    Returns:
        S_OK indicates success, means we grab the mutex and updated each setting handlers
        S_FALSE means we didn't get the mutex right away, so we set a timer for retry
        otherwise failure
------------------------------------------------------------------------------*/
HRESULT
Settings_t::NotifySettingHandlers(
    DWORD   UpdatedSettingFlags
    )
{
    if (m_VoIPSettingMutex == NULL)
    {
        return E_UNEXPECTED;
    }

    HRESULT hr          = S_OK;
    bool    GotMutex    = false;

    //check whether we need to aquire the mutex, if so, get the mutex
    //note: if the setting is only phone status flags change, we don't need to get the mutex,
    //the setting can be dispatched to Connection Manager directly, otherwise, we have to get
    //the mutex first
    if (UpdatedSettingFlags != SEF_NONE)
    {
        //for all the sttings except SEF_PHONE_STATUS_FLAGS, we need to get mutex first
        DWORD Result = WaitForSingleObject(
                            m_VoIPSettingMutex,
                            0
                            );

        switch(Result)
        {
            case WAIT_TIMEOUT:
                //if we don't get timer right away, set the pending setting flags
                m_PendingSettingUpdateFlags = UpdatedSettingFlags;

                //fire up a timer for later re-try            
                hr = (GetApp()->GetTimers()).AddTimer(
                                    sc_RetryTimeout, 
                                    static_cast<ITimerHandler_t*>(this), 
                                    &m_RetryTimerIdentifier
                                    );

                if (FAILED(hr))
                {
                    return E_FAIL;
                }

                return S_FALSE;

            case WAIT_FAILED:
                //fall through to the WAIT_TIME out case
                hr = CommonUtilities_t::GetErrorFromWin32();
                PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at waitting for VoIP Settings mutex, hr = 0x%x", hr));
                return hr;

            case WAIT_OBJECT_0:
            case WAIT_ABANDONED:
                GotMutex = true;
                break;

            default:
                ASSERT(FALSE); //not possible got here
                return E_FAIL;
        }

    }

    // Duplicate the file with the new settings for DialPlan
    if (UpdatedSettingFlags & SEF_VOIP_DIALPLAN)
    {
        WCHAR FileName[MAX_PATH] = L"";
        hr = GetSettingFileName(
                        m_pActiveFilePrefix,
                        sc_VoIPSettings[SettingTypeDialPlan].pSettingName,
                        FileName,
                        ARRAYSIZE(FileName)
                        );
        if (SUCCEEDED(hr))
        {
            //set the dialplan file to NORMAL attribute so that it can be re-written
            SetFileAttributes(sc_DialPlanFile, FILE_ATTRIBUTE_NORMAL); 

            //copy the dial plan file from provision location
            if (!CopyFile(FileName, sc_DialPlanFile, FALSE))
            {
                hr = CommonUtilities_t::GetErrorFromWin32(); 
                PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at copying data, hr = 0x%x", hr)); 
            }
        }

        if (FAILED(hr))
        {
            //if error happens during copy, wipe out the old dial plan and continue with other settings
            DeleteFile(sc_DialPlanFile); 
        }
    }

    //we got the mutx, now go through the setting handler list to notify each handler
    //Note: there might be a chance that when a setting handler handles the setting change, it will
    //trigger another setting handlers to unregister/register itself to this list. for example,
    //when ConnectionManager_t handles the network prefereence setting change, it will most likely to
    //trigger the DialEngine_t and VoIPPhoneCanvas_t register/unregister themselve to this list.
    //But in this scenario we are safe here, because
    // 1: ConnectionManager_t will always be there in the list and always be the first one
    // 2: after DialEngine_t and VoIPPhoneCanvas_t register/unregister themselves to the list, the iteraotr
    // will get adjusted as well, so we don't have to worry about a invalid iterator.
    // 3: None of the setting handlers will unregister itself when it handles its setting flags
    for (HandlerList_t::iterator SettingHandlerMapping  = m_HandlerList.begin();
        SettingHandlerMapping != m_HandlerList.end(); SettingHandlerMapping++)
    {
        //notify the setting handler if setting flag matches
        if (UpdatedSettingFlags & ((*SettingHandlerMapping).SettingFlags))
        {
            ((*SettingHandlerMapping).pSettingChangeHandler)->OnSettingsChange(UpdatedSettingFlags);
        }
    }

    //release the mutex
    if (GotMutex)
    {
        ReleaseMutex(m_VoIPSettingMutex);
    }

    return S_OK;

}

/*------------------------------------------------------------------------------
    Settings_t::RegisterHandler

    Register a setting handler

    Parameters:
        SettingFlags:       [in] the DWORD of the setting flags
        pSettingHandler:    [in] the pointer to the ISettingChangeHandler_t interface

    Returns:    S_OK indicates success, otherwise failed
------------------------------------------------------------------------------*/
HRESULT
Settings_t::RegisterHandler(
    DWORD                      SettingFlags,
    ISettingChangeHandler_t*   pSettingHandler
    )
{
    ASSERT(pSettingHandler != NULL);

    //if we don't find one existed, we need to add a new one!
    SettingHandlerMapping_t NewHandlerMapping = {SettingFlags, pSettingHandler};

    //always push the new handler at the end of the handler list
    if (! m_HandlerList.push_back(NewHandlerMapping))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - could not push the new call onto the call list"));
        return E_OUTOFMEMORY;
    }

    return S_OK;

}

/*------------------------------------------------------------------------------
    Settings_t::UnregisterHandler

    Unregister a setting handler that used to handle certain setting flags

    Parameters:
        pSettingHandler:       [in] the pointer of the ISettingChangeHandler_t object

    Returns:    S_OK indicates success, otherwise failed
------------------------------------------------------------------------------*/
HRESULT
Settings_t::UnregisterHandler(
    ISettingChangeHandler_t*    pSettingHandler
    )
{
    ASSERT(pSettingHandler != NULL);

    for (HandlerList_t::iterator SettingHandlerMapping = m_HandlerList.begin();
        SettingHandlerMapping != m_HandlerList.end(); SettingHandlerMapping ++)
    {
        if ((*SettingHandlerMapping).pSettingChangeHandler == pSettingHandler)
        {
            m_HandlerList.erase(SettingHandlerMapping);
            return S_OK;
        }
    }

    return E_INVALIDARG;

}

/*------------------------------------------------------------------------------
    Settings_t::GetUpdatedVoIPSettingFlags

    Find out what VoIP setting flags have been updated

    Parameters: None

    Returns:    DWORD that specify what VoIP Setting flag have been updated
------------------------------------------------------------------------------*/
DWORD
Settings_t::GetUpdatedVoIPSettingFlags(
    void
    )
{
    struct VSF_SEF_Mapping
    {
        DWORD VSF_FLAG;
        DWORD SEF_FLAG;
    };

    //mapping array between VSF_ flags to SEF_ flags
    static struct VSF_SEF_Mapping VSF_SEF_Array[] =
    {
        {VOIP_SIP_SETTINGS_BITMASK,          SEF_VOIP_SIP_SETTINGS},
        {VOIP_VOICEMAIL_SETTINGS_BITMASK,    SEF_VOIP_VOICEMAIL_SETTINGS},
        {VOIP_VOICEMAIL_NUMBER_BITMASK,      SEF_VOIP_VOICEMAIL_NUMBER},
        {VOIP_BACKUP_SIP_SETTINGS_BITMASK,   SEF_VOIP_BACKUP_SIP_SETTINGS},
        {VOIP_DIALPLAN_BITMASK,              SEF_VOIP_DIALPLAN},
    };

    DWORD   UpdatedSettings = 0; 
    DWORD   UpdatedVoIPSettingFlags = 0;

    HRESULT hr = RegistryGetDWORD(
                    SN_VOIP_UPDATEDSETTINGS_ROOT, 
                    SN_VOIP_UPDATEDSETTINGS_PATH, 
                    SN_VOIP_UPDATEDSETTINGS_VALUE, 
                    &UpdatedSettings
                    );                     
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at getting statstore data, hr =0x%x", hr));
        goto exit;
    }

    //adjust the registry key name and file prefix for current 'active' settings
    if (UpdatedSettings & VOIP_UPDATEDSETTINGS_ACTIVEREG_BITMASK)
    {
        m_pActiveFilePrefix = Settings_t::sc_SettingFilePrefix1;
        m_pActiveRegKeyName = REG_szSecurityVoIPPhoneSetting_ProvisioningKey1;
    }
    else
    {
        //otherwise, set it to default value
        m_pActiveFilePrefix = Settings_t::sc_SettingFilePrefix0;
        m_pActiveRegKeyName = REG_szSecurityVoIPPhoneSetting_ProvisioningKey0;
    }

    //map the flags from VSF_ to SEF_
    for (int Index = 0; Index < ARRAYSIZE(VSF_SEF_Array); Index ++)
    {
        if (UpdatedSettings & VSF_SEF_Array[Index].VSF_FLAG)
        {
            UpdatedVoIPSettingFlags |= VSF_SEF_Array[Index].SEF_FLAG;
        }
    }


exit:

    return UpdatedVoIPSettingFlags;

}

/*------------------------------------------------------------------------------
    Settings_t::InitializeActiveRegKeyNameAndFilePrefix

    query the statstore flag SDID_VOIP_UPDATEDSETTINGS to initialize active reg sub key name
    and active file namre prefix, so that we know where we should read data from

    Parameters:
        none

    Returns:    S_OK indicates success, otherwise failed
------------------------------------------------------------------------------*/
HRESULT
Settings_t::InitializeActiveRegKeyNameAndFilePrefix(
        void
        )
{

    DWORD   UpdatedSettings; 

    HRESULT hr = RegistryGetDWORD(
                    SN_VOIP_UPDATEDSETTINGS_ROOT, 
                    SN_VOIP_UPDATEDSETTINGS_PATH, 
                    SN_VOIP_UPDATEDSETTINGS_VALUE, 
                    &UpdatedSettings
                    ); 

    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at getting statstore data, hr =0x%x", hr));
        UpdatedSettings = 0; 
    }
    
    //check out the registry key name and file prefix for current 'active' settings
    if (UpdatedSettings & VOIP_UPDATEDSETTINGS_ACTIVEREG_BITMASK)
    {
        m_pActiveFilePrefix = Settings_t::sc_SettingFilePrefix1;
        m_pActiveRegKeyName = REG_szSecurityVoIPPhoneSetting_ProvisioningKey1;

    }
    else
    {
        //otherwise, set it to default value, this includes the scenario that
        //the statstore value is not there yet
        m_pActiveFilePrefix = Settings_t::sc_SettingFilePrefix0;
        m_pActiveRegKeyName = REG_szSecurityVoIPPhoneSetting_ProvisioningKey0;

    }

    return S_OK;

}


/*------------------------------------------------------------------------------
    Settings_t::GetRegistrationProfile

    Get the main registry RTC profile

    Parameters:
        SIPSettingsType:        [in] indicates this is a Main SIP server or Backup SIP server
        ppRegistrationProfile:  [out] pointer to a pointer which points the a IRTCProfile object

    Returns:    S_OK indicates success, otherwise failed
------------------------------------------------------------------------------*/
HRESULT
Settings_t::GetRegistrationProfile(
    SettingType_e                   SIPSettingsType, 
    __deref_out_opt IRTCProfile**   ppRegistrationProfile
    )

{
    ASSERT(ppRegistrationProfile != NULL); 

    if ((SIPSettingsType != SettingTypeSIPSettings) && (SIPSettingsType != SettingTypeBackupSIPSettings))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -