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

📄 settings.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "Settings.hpp"
#include "Common.hpp"
#include "CommonFunctions.hpp"  //for common functions
#include <Wincrypt.h>           //for DPAPI
#include <auto_xxx.hxx>         //for auto_bstr, auto_hfile, auto_hfine etc
#include "VoIPApp.hpp"
#include "VoIPNotify.hpp"
#include "Debug.hpp"
#include "DatabaseAPI.hpp"

Setting_t::Setting_t(
    HKEY            RootKey, 
    const WCHAR*    c_pSubKey, 
    const WCHAR*    c_pValueName
    )
{
    if (
        (RootKey == NULL) ||
        (c_pSubKey == NULL) || (c_pSubKey[0] == NULL) ||
        (c_pValueName == NULL) || (c_pValueName[0] == NULL)
        )
    {
        ASSERT(FALSE); 
    }

    m_NotifyHandle = NULL; 
    m_RootKey = RootKey; 
    
    if (
        !m_SubKey.assign(c_pSubKey) ||
        !m_ValueName.assign(c_pValueName)
        )
    {
        ASSERT(FALSE); 
    }

}

Setting_t::~Setting_t(
    void
    )
{
    if (m_NotifyHandle != NULL)
    {
        HRESULT hr = RegistryCloseNotification(
                        m_NotifyHandle
                        ); 
        if (FAILED(hr))
        {
            ASSERT(FALSE);         
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at closing the registry notification, error = 0x%x", hr)); 
        }        
    }
    
}

HRESULT
Setting_t::RegisterForNotification(
    HWND    WindowHandle, 
    UINT    Message, 
    DWORD   UserData
    )
{
    if (WindowHandle == NULL)
    {
        return E_INVALIDARG; 
    }

    return RegistryNotifyWindow(
            m_RootKey, 
            m_SubKey, 
            m_ValueName, 
            WindowHandle, 
            Message, 
            UserData, 
            NULL, 
            &m_NotifyHandle
            ); 
}



StringSetting_t::StringSetting_t(
    HKEY            RootKey, 
    const WCHAR*    c_pSubKey, 
    const WCHAR*    c_pValueName, 
    const WCHAR*    pDefaultValue
    ) : Setting_t(RootKey, c_pSubKey, c_pValueName)
{
    if ((pDefaultValue != NULL) && 
        (pDefaultValue[0] != NULL))
    {
        if (!m_DefaultValue.assign(pDefaultValue))
        {
            ASSERT(FALSE); 
        }
    }

    Update(); 
    
}

HRESULT
StringSetting_t::Update(
    void
    )
{
    WCHAR Value[MAX_PATH] = L""; 
    HRESULT hr = RegistryGetString(
                    m_RootKey, 
                    m_SubKey, 
                    m_ValueName, 
                    Value, 
                    ARRAYSIZE(Value)
                    ); 
    if (FAILED(hr))
    {
        if (!m_SettingValue.assign(m_DefaultValue))
        {
            return E_OUTOFMEMORY; 
        }
        
        return hr; 
    }

    if (!m_SettingValue.assign(Value))
    {
        return E_OUTOFMEMORY; 
    }
    
    return hr; 
}
    
IntegerSetting_t::IntegerSetting_t(
    HKEY            RootKey, 
    const WCHAR*    c_pSubKey, 
    const WCHAR*    c_pValueName, 
    DWORD           DefaultValue
    ) : Setting_t(RootKey, c_pSubKey, c_pValueName)
{
    m_DefaultValue = (DefaultValue == -1) ? 0 : DefaultValue; 

    Update(); 
}


HRESULT
IntegerSetting_t::Update(
    void
    )
{
    HRESULT hr = RegistryGetDWORD(
                    m_RootKey, 
                    m_SubKey, 
                    m_ValueName, 
                    &m_SettingValue
                    ); 

    if (FAILED(hr))
    {
        m_SettingValue = m_DefaultValue; 
    }

    return hr; 
}

///TODO: Need to consolidate those constants with Provision classes

#define REG_szSecurityVoIPPhoneSetting_ProvisioningKey0 TEXT("Security\\Phone\\VoIP\\Provisioning0")
#define REG_szSecurityVoIPPhoneSetting_ProvisioningKey1 TEXT("Security\\Phone\\VoIP\\Provisioning1")

#define WM_CHANGE_PROVISION_SETTINGS        (WM_USER + 1)
#define WM_CHANGE_PHONE_SETTINGS            (WM_USER + 2)

//public static constants, they are shared by both VoIPCSP_t and Settings_t
const Settings_t::VoIPSetting Settings_t::sc_VoIPSettings[] =
{
    {SettingTypeSIPSettings,        L"SIPSettings",         true,   StorageTypeFile,    VOIP_SIP_SETTINGS_BITMASK,           L"SIPSettings"},
    {SettingTypeVoicemailSettings,  L"VoicemailSettings",   true,   StorageTypeFile,    VOIP_VOICEMAIL_SETTINGS_BITMASK,     L"VoicemailSettings"},
    {SettingTypeVoicemailNumber,    L"VoicemailNumber",     false,  StorageTypeRegistry,VOIP_VOICEMAIL_NUMBER_BITMASK,       L"VoicemailNumber"},
    {SettingTypeBackupSIPSettings,  L"BackupSIPSettings",   true,   StorageTypeFile,    VOIP_BACKUP_SIP_SETTINGS_BITMASK,    L"BackupSIPSettings"},
    {SettingTypeDialPlan,           L"DialPlan",            false,  StorageTypeFile,    VOIP_DIALPLAN_BITMASK,               L"DialPlan"},
};

const int   Settings_t::sc_NumberOfVoIPSettings     = ARRAYSIZE(Settings_t::sc_VoIPSettings);

//the 'SYSTEM/' prefix prevents untrusted applications from creating/opening this mutex. 
const WCHAR Settings_t::sc_VoIPSettingsMutexName[]  = L"SYSTEM/VoIPSettingsMutex";

const UINT  Settings_t::sc_RetryTimeout             = 60 * 1000; // time out value for re-try: 1 min

const WCHAR Settings_t::sc_SettingFilePrefix0[]     = L"\\windows\\VoIP\\Prov0";
const WCHAR Settings_t::sc_SettingFilePrefix1[]     = L"\\windows\\VoIP\\Prov1";
const WCHAR Settings_t::sc_SettingFileDirectory[]   = L"\\windows\\VoIP\\";

const WCHAR Settings_t::sc_DialPlanFile[]           = L"\\windows\\VoIP\\DialPlan";

//private static constants
const WCHAR Settings_t::sc_ListenerWindowClassName[]  = L"VoIPSettingManagerListener";

const WCHAR Settings_t::sc_DefaultRingTone[]          = L"\\Windows\\ring.wav"; 

StringSetting_t     
Settings_t::s_ForwardingNumber(
                    SN_VOIP_FORWARDINGNUMBER_ROOT, 
                    SN_VOIP_FORWARDINGNUMBER_PATH, 
                    SN_VOIP_FORWARDINGNUMBER_VALUE
                    ); 

const UINT  Settings_t::s_dwGenerateKeydown = 100; 
const UINT  Settings_t::s_msPressAndHold    = 100; 
const UINT  Settings_t::s_msInactivityTimeout = 180000; // 3 mins

Setting_t* Settings_t::s_PhoneSettings[] = 
{
    &Settings_t::s_ForwardingNumber, 
}; 

/*------------------------------------------------------------------------------
    LoadXMLIntoBSTR

    helper function to load an XML file to a BSTR

    NOTE: copy from private\apps\tpcutil\settings.cpp

    this function will go away after we have the bootstrapping xml file in place
------------------------------------------------------------------------------*/
HRESULT LoadXMLIntoBSTR(
    HANDLE                hFile,
    __deref_out_opt BSTR* pbstrOutput
    )
{
    HRESULT hr              = S_OK;
    LPSTR   pszLoadedData   = NULL;
    DWORD   dwFileSize      = 0;
    DWORD   dwRead          = 0;
    DWORD   dwBSTRLen       = 0;
    BSTR    bstrText        = NULL;

    ASSERT(hFile != INVALID_HANDLE_VALUE);
    ASSERT(pbstrOutput != NULL);

    dwFileSize = GetFileSize(hFile, NULL);
    if (0xFFFFFFFF == dwFileSize)
    {
        hr = CommonUtilities_t::GetErrorFromWin32();
        goto Error;
    }

    // Allocate return buffer, allowing space for the NUL terminator
    pszLoadedData = (LPSTR)LocalAlloc(LMEM_FIXED, dwFileSize+1);
    if (!pszLoadedData)
    {
        hr = E_OUTOFMEMORY;
        goto Error;
    }

    if (!ReadFile(hFile, pszLoadedData, dwFileSize, &dwRead, 0))
    {
        hr = CommonUtilities_t::GetErrorFromWin32();
        goto Error;
    }

    if (dwRead != dwFileSize)
    {
        ASSERT(0);
        hr = E_FAIL;
        goto Error;
    }

    // NULL terminate the input file
    pszLoadedData[dwFileSize] = '\0';

    dwBSTRLen = MultiByteToWideChar(CP_UTF8, 0, pszLoadedData, -1, NULL, 0);
    if (dwBSTRLen == 0)
    {
        hr = E_FAIL;
        goto Error;
    }

    bstrText = SysAllocStringLen(NULL, dwBSTRLen);
    if (!bstrText)
    {
        hr = E_OUTOFMEMORY;
        goto Error;
    }

    if (dwBSTRLen != (DWORD)MultiByteToWideChar(CP_UTF8, 0, pszLoadedData, -1, bstrText, dwBSTRLen + 1))
    {
        hr = E_FAIL;
        goto Error;
    }

    // Hand off memory
    *pbstrOutput = bstrText;
    bstrText = NULL;

Error:
    if (pszLoadedData)
    {
        LocalFree(pszLoadedData);
    }

    if (bstrText != NULL)
    {
        SysFreeString(bstrText);
    }

    return hr;
}



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

    constructor
------------------------------------------------------------------------------*/
Settings_t::Settings_t() :
    m_ListenerWindow(NULL),
    m_pActiveRegKeyName(NULL),
    m_pActiveFilePrefix(NULL),
    m_VoIPSettingMutex(INVALID_HANDLE_VALUE),
    m_RetryTimerIdentifier(0),
    m_PendingSettingUpdateFlags(SEF_NONE)
{
    ; 
}

/*------------------------------------------------------------------------------
    Settings_t::~Settings_t

    destructor
------------------------------------------------------------------------------*/
Settings_t::~Settings_t()
{
    if (m_HandlerList.size() != 0)
    {
        m_HandlerList.clear();
    }

    if (m_ListenerWindow)
    {
        DestroyWindow(m_ListenerWindow);
        m_ListenerWindow = NULL;
    }

    if (m_NotifyHandleForProvisionSettings)
    {
        RegistryCloseNotification(m_NotifyHandleForProvisionSettings); 
    }

    //clean up the mutex handle
    if (m_VoIPSettingMutex != NULL)
    {
        //close the mutex handle
        CloseHandle(m_VoIPSettingMutex);
        m_VoIPSettingMutex = INVALID_HANDLE_VALUE;
    }

    UnregisterClass(sc_ListenerWindowClassName, GlobalData_t::s_ModuleInstance);
}

/*------------------------------------------------------------------------------
    Settings_t::Initialize

    initializes the Settings_t object

    Parameters:
        pVoIPPhoneCanvas:    [IN] the pointer to the VoIPPhoneCanvas_t object
        
    Returns:    S_OK indicates success, otherwise failed
------------------------------------------------------------------------------*/
HRESULT
Settings_t::Initialize(
    void
    )
{
    HRESULT hr = S_OK;

    //open the mutex first, if it failed, bail out
    m_VoIPSettingMutex = CreateMutex(
                                NULL,
                                false,
                                sc_VoIPSettingsMutexName
                                );

    if (m_VoIPSettingMutex == NULL)
    {
        hr = CommonUtilities_t::GetErrorFromWin32();
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at creating/opening the VoIP settings mutex, hr =0x%x", hr));
        return hr;
    }

    //register the listener window class
    WNDCLASS WindowClass        = {0};
    WindowClass.lpfnWndProc     = s_ListenerWindowProc;
    WindowClass.hInstance       = GlobalData_t::s_ModuleInstance;
    WindowClass.lpszClassName   = sc_ListenerWindowClassName;

    //it's ok if our class already exists...
    if (! RegisterClass(&WindowClass))
    {
        int LastError = GetLastError();
        if (LastError != ERROR_CLASS_ALREADY_EXISTS)
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Could not register Listener window class - LastError=%08X", LastError));
            return CommonUtilities_t::GetErrorFromWin32();
        }
    }

    //create the notification window and pack our 'this' pointer into the CREATESTRUCT
    m_ListenerWindow = CreateWindow(
                        sc_ListenerWindowClassName,
                        NULL,
                        0,
                        0,
                        0,
                        0,
                        0,
                        NULL,
                        NULL,
                        GlobalData_t::s_ModuleInstance,
                        reinterpret_cast<VOID*>(this)
                        );
    if (m_ListenerWindow == NULL)
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Could not create the listener window - LastError=%08X", GetLastError()));
        return CommonUtilities_t::GetErrorFromWin32();
    }

    //initialize the active reg key name and file name prefix
    hr = InitializeActiveRegKeyNameAndFilePrefix();
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"could not initialize the active regkey name and file prefix, hr = 0x%x", hr));
    }

    return hr;
}

/*------------------------------------------------------------------------------
    Settings_t::StartListening

    Star to listen the stat store setting changes

    Parameters:
        none

    Returns:    S_OK indicates success, otherwise failed
------------------------------------------------------------------------------*/
HRESULT
Settings_t::StartListening(
    void
    )
{
    ///TODO: consider encapusulate the provision settings into another Setting_t class
    HRESULT hr = RegistryNotifyWindow(
                    SN_VOIP_UPDATEDSETTINGS_ROOT, 
                    SN_VOIP_UPDATEDSETTINGS_PATH, 
                    SN_VOIP_UPDATEDSETTINGS_VALUE, 
                    m_ListenerWindow, 
                    WM_CHANGE_PROVISION_SETTINGS, 
                    0, 
                    NULL, 
                    &m_NotifyHandleForProvisionSettings
                    ); 

    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Could not register callback for StatStore notifications"));            
        return hr;             
    }

    for (int Index = 0; Index < ARRAYSIZE(s_PhoneSettings); Index ++)
    {
        hr = s_PhoneSettings[Index]->RegisterForNotification(
                m_ListenerWindow, 

⌨️ 快捷键说明

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