📄 settingsapi.cpp
字号:
//
// 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 <CReg.hxx>
#include <SettingsAPI.hpp>
#include <VoIPNotify.hpp>
#include "VolumeAPI.hpp"
#include <Common.hpp>
#include <RegExt.h>
#include <Debug.hpp>
#include <CommandAPI.hpp>
#include <wincrypt.h>
inline
bool
GetSettingRegPath(
PHSetting Setting,
__deref_out_opt HKEY* pRoot,
__deref_out_opt const WCHAR** ppPath,
__deref_out_opt const WCHAR** ppValue
)
{
switch (Setting)
{
case phsAutoDial:
*pRoot = SN_VOIP_AUTODIAL_ROOT;
*ppPath = SN_VOIP_AUTODIAL_PATH;
*ppValue = SN_VOIP_AUTODIAL_VALUE;
break;
case phsCallForwarding:
*pRoot = SN_VOIP_CALLFORWARDING_ROOT;
*ppPath = SN_VOIP_CALLFORWARDING_PATH;
*ppValue = SN_VOIP_CALLFORWARDING_VALUE;
break;
case phsDoNotDisturb:
*pRoot = SN_VOIP_DONOTDISTURB_ROOT;
*ppPath = SN_VOIP_DONOTDISTURB_PATH;
*ppValue = SN_VOIP_DONOTDISTURB_VALUE;
break;
case phsBlockCallerId:
*pRoot = SN_VOIP_BLOCKCALLERID_ROOT;
*ppPath = SN_VOIP_BLOCKCALLERID_PATH;
*ppValue = SN_VOIP_BLOCKCALLERID_VALUE;
break;
case phsMissedCalls:
*pRoot = SN_VOIP_NEWMISSEDCALLS_ROOT;
*ppPath = SN_VOIP_NEWMISSEDCALLS_PATH;
*ppValue = SN_VOIP_NEWMISSEDCALLS_VALUE;
break;
case phsIncomingCalls:
*pRoot = SN_VOIP_NEWINCOMINGCALLS_ROOT;
*ppPath = SN_VOIP_NEWINCOMINGCALLS_PATH;
*ppValue = SN_VOIP_NEWINCOMINGCALLS_VALUE;
break;
case phsOutgoingCalls:
*pRoot = SN_VOIP_NEWOUTGOINGCALLS_ROOT;
*ppPath = SN_VOIP_NEWOUTGOINGCALLS_PATH;
*ppValue = SN_VOIP_NEWOUTGOINGCALLS_VALUE;
break;
case phsGalFilterType:
*pRoot = SN_VOIP_GALFILTERTYPE_ROOT;
*ppPath = SN_VOIP_GALFILTERTYPE_PATH;
*ppValue = SN_VOIP_GALFILTERTYPE_VALUE;
break;
case phsContactFilterType:
*pRoot = SN_VOIP_CONTACTFILTERTYPE_ROOT;
*ppPath = SN_VOIP_CONTACTFILTERTYPE_PATH;
*ppValue = SN_VOIP_CONTACTFILTERTYPE_VALUE;
break;
case phsDeviceLocked:
*pRoot = SN_VOIP_ISLOCKED_ROOT;
*ppPath = SN_VOIP_ISLOCKED_PATH;
*ppValue = SN_VOIP_ISLOCKED_VALUE;
break;
case phsAutoDialRulesAvailability:
*pRoot = SN_VOIP_AUTODIALRULES_ROOT;
*ppPath = SN_VOIP_AUTODIALRULES_PATH;
*ppValue = SN_VOIP_AUTODIALRULES_VALUE;
break;
case phsPhoneAppStatus:
*pRoot = SN_VOIP_PHONEAPPSTATUS_ROOT;
*ppPath = SN_VOIP_PHONEAPPSTATUS_PATH;
*ppValue = SN_VOIP_PHONEAPPSTATUS_VALUE;
break;
case phsDisableAGC:
*pRoot = SN_VOIP_DISABLEAGC_ROOT;
*ppPath = SN_VOIP_DISABLEAGC_PATH;
*ppValue = SN_VOIP_DISABLEAGC_VALUE;
break;
case phsLockPhoneAfterUpdatingPIN:
*pRoot = SN_VOIP_LockPhoneAfterUpdatingPIN_ROOT;
*ppPath = SN_VOIP_LockPhoneAfterUpdatingPIN_PATH;
*ppValue = SN_VOIP_LockPhoneAfterUpdatingPIN_VALUE;
break;
default:
ASSERT(FALSE);
return false;
}
return true;
}
EXTERN_C
DWORD
PHGetSetting(
PHSetting Setting
)
{
HKEY Root;
const WCHAR* pPath = NULL;
const WCHAR* pValue = NULL;
if (! GetSettingRegPath(
Setting,
&Root,
&pPath,
&pValue
))
{
COMMON_RETAILMSG(ZONE_COMMON_ERROR, (L"Invalid argument to PHGetSetting: %d", Setting));
return 0;
}
DWORD Data = 0;
HRESULT hr = RegistryGetDWORD(
Root,
pPath,
pValue,
&Data
);
if (FAILED(hr))
{
//couldn't open the key
return 0;
}
return Data;
}
EXTERN_C
HRESULT
PHSetValue(
PHSetting Setting,
DWORD Value
)
{
HKEY Root;
const WCHAR* pPath = NULL;
const WCHAR* pValue = NULL;
if (! GetSettingRegPath(
Setting,
&Root,
&pPath,
&pValue
))
{
COMMON_RETAILMSG(ZONE_COMMON_ERROR, (L"Invalid argument to PHEnableSetting: %d", Setting));
return E_INVALIDARG;
}
HRESULT hr = RegistrySetDWORD(
Root,
pPath,
pValue,
Value
);
if (FAILED(hr))
{
COMMON_RETAILMSG(ZONE_COMMON_ERROR, (L"Failed writing the registry value 0x%x", hr));
return hr;
}
return S_OK;
}
/*------------------------------------------------------------------------------
PHAuthenticateUser
Determine if the user is authenticated, and if not, then challenge
the user for authentication.
------------------------------------------------------------------------------*/
EXTERN_C
HRESULT
PHAuthenticateUser(
PH_AUTHENTICATE_USER_PARAMETERS* pParams
)
{
//first validate the parameters
if (! pParams || pParams->StructSize != sizeof(PH_AUTHENTICATE_USER_PARAMETERS))
{
COMMON_RETAILMSG(ZONE_COMMON_ERROR, (L"Invalid parameters!"));
ASSERT(FALSE);
return E_INVALIDARG;
}
//
// Initialize the out parameters
//
pParams->Result = AuthCanceled;
//check if the device is already unlocked
if (! PHGetSetting(phsDeviceLocked))
{
pParams->Result = AuthSucceeded;
return S_OK;
}
//Device is locked, challenge the user in the homescreen...
//
// Validate the next set of parameters...
//
if (! IsWindow(pParams->NotificationWindow) || ! pParams->NotificationMessage)
{
COMMON_RETAILMSG(ZONE_COMMON_ERROR, (L"Invalid parameters!"));
ASSERT(FALSE);
return E_INVALIDARG;
}
HWND HomeScreenWindow = PHGetAppWindow(
phaHomeScreenApp,
FALSE
);
if (! HomeScreenWindow)
{
COMMON_RETAILMSG(ZONE_COMMON_ERROR, (L"Cannot find the homescreen window - failing PHAuthenticateUser"));
return HRESULT_FROM_WIN32(ERROR_NOACCESS);
}
HRESULT hr = (HRESULT)SendMessage(
HomeScreenWindow,
WM_AUTHENTICATE_USER,
(WPARAM)pParams->NotificationMessage,
(LPARAM)pParams->NotificationWindow
);
if (SUCCEEDED(hr))
{
pParams->Result = AuthInProgress;
}
return hr;
}
/*------------------------------------------------------------------------------
PHCancelAuthenticationRequest
Cancel an existing authentication request
------------------------------------------------------------------------------*/
EXTERN_C
HRESULT
PHCancelAuthenticationRequest(
HWND hwnd
)
{
if (! IsWindow(hwnd))
{
return E_HANDLE;
}
HWND AppWnd = PHGetAppWindow(
phaHomeScreenApp,
FALSE
);
if (! AppWnd)
{
return E_FAIL;
}
return (HRESULT)SendMessage(
AppWnd,
WM_CANCEL_AUTH_REQUEST,
0,
(LPARAM)hwnd
);
}
/*------------------------------------------------------------------------------
PHWritePIN
Encrypt the PIN and write it to the registry
------------------------------------------------------------------------------*/
EXTERN_C
HRESULT
PHWritePIN(
__in const WCHAR* pPinString
)
{
if (! pPinString)
{
ASSERT(FALSE);
return E_POINTER;
}
int Length = wcslen(pPinString);
if (! Length)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
//add room for the NULL terminator
Length++;
HRESULT hr;
CReg reg;
DATA_BLOB InBlob;
DATA_BLOB OutBlob = {0};
InBlob.cbData = Length*sizeof(WCHAR);
InBlob.pbData = reinterpret_cast<BYTE*>(const_cast<WCHAR*>(pPinString));
//encrypt the data
if (! CryptProtectData(
&InBlob,
NULL, NULL, NULL, NULL,
CRYPTPROTECT_SYSTEM,
&OutBlob
))
{
hr = CommonUtilities_t::GetErrorFromWin32();
goto exit;
}
if (! OutBlob.cbData || ! OutBlob.pbData)
{
ASSERT(FALSE);
hr = E_FAIL;
goto exit;
}
//store it in the registry as binary data
if (! reg.OpenOrCreateRegKey(
SN_VOIP_ENCRYPTEDPIN_ROOT,
SN_VOIP_ENCRYPTEDPIN_PATH,
KEY_WRITE
))
{
hr = CommonUtilities_t::GetErrorFromWin32();
goto exit;
}
if (! reg.SetBinary(
SN_VOIP_ENCRYPTEDPIN_VALUE,
OutBlob.pbData,
OutBlob.cbData
))
{
hr = CommonUtilities_t::GetErrorFromWin32();
goto exit;
}
hr = S_OK;
exit:
if (OutBlob.pbData)
{
LocalFree(OutBlob.pbData);
}
return hr;
}
/*------------------------------------------------------------------------------
PHReadPIN
Read the encrypted PIN value out of the registry
------------------------------------------------------------------------------*/
EXTERN_C
HRESULT
PHReadPIN(
__out_ecount(BufferLength) WCHAR* pPinBuffer,
int BufferLength
)
{
if (! pPinBuffer || ! BufferLength)
{
return E_FAIL;
}
HKEY hkey = NULL;
HRESULT hr = S_OK;
DWORD DataSize = 0;
DATA_BLOB InBlob;
DATA_BLOB OutBlob = {0};
BYTE* pEncryptedData = NULL;
//Open the key containing the data
DWORD Err = RegOpenKeyEx(
SN_VOIP_ENCRYPTEDPIN_ROOT,
SN_VOIP_ENCRYPTEDPIN_PATH,
0,
0,
&hkey
);
if (Err != ERROR_SUCCESS)
{
return CommonUtilities_t::GetErrorFromWin32();
}
//calculate the buffer size required
Err = RegQueryValueEx(
hkey,
SN_VOIP_ENCRYPTEDPIN_VALUE,
NULL, //reserved
NULL, //type
NULL, //data - NULL, we want the size
&DataSize
);
if (Err != ERROR_INSUFFICIENT_BUFFER && Err != ERROR_SUCCESS)
{
hr = HRESULT_FROM_WIN32(Err);
goto exit;
}
//allocate a buffer large enough to hold the data
pEncryptedData = reinterpret_cast<BYTE*>(TrackAlloc(DataSize));
if (! pEncryptedData)
{
hr = E_OUTOFMEMORY;
goto exit;
}
//read in the actual data
Err = RegQueryValueEx(
hkey,
SN_VOIP_ENCRYPTEDPIN_VALUE,
NULL,
NULL,
pEncryptedData,
&DataSize
);
if (Err != ERROR_SUCCESS)
{
hr = HRESULT_FROM_WIN32(Err);
goto exit;
}
InBlob.cbData = DataSize;
InBlob.pbData = pEncryptedData;
//Decrypt the data
if (! CryptUnprotectData(
&InBlob,
NULL, NULL, NULL, NULL,
CRYPTPROTECT_SYSTEM,
&OutBlob
))
{
hr = CommonUtilities_t::GetErrorFromWin32();
goto exit;
}
if (! OutBlob.pbData)
{
ASSERT(FALSE);
hr = E_FAIL;
goto exit;
}
__try
{
//try to read the data back as a string!
hr = StringCchCopy(
pPinBuffer,
BufferLength,
reinterpret_cast<WCHAR*>(OutBlob.pbData)
);
if (FAILED(hr))
{
pPinBuffer[0] = 0;
goto exit;
}
}
__except (1)
{
COMMON_RETAILMSG(ZONE_COMMON_ERROR, (L"Caught exception while converting protected PIN to a string...deleting the PIN..."));
RegDeleteValue(hkey, SN_VOIP_ENCRYPTEDPIN_VALUE);
hr = E_FAIL;
goto exit;
}
hr = S_OK;
exit:
if (OutBlob.pbData)
{
LocalFree(OutBlob.pbData);
}
if (pEncryptedData)
{
TrackFree(pEncryptedData);
}
RegCloseKey(hkey);
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -