windows-nt/Source/XPSP1/NT/net/config/netcfg/netcomm/value.cpp
2020-09-26 16:20:57 +08:00

485 lines
9.9 KiB
C++

#include "pch.h"
#pragma hdrstop
#include "global.h"
#include "value.h"
#include "util.h"
#include "ncreg.h"
#include "ncstring.h"
static const int c_valueSzMax;
CValue::CValue()
: m_fInit(FALSE),
m_eType(VALUETYPE_UNKNOWN),
m_fNumeric(FALSE),
m_fHex(FALSE),
m_fPresent(FALSE),
m_fInvalidChars(FALSE),
m_fEmptyString(FALSE),
m_psz(0)
{
}
CValue::~CValue()
{
#ifdef DBG
if (!m_fNumeric)
{
AssertSz(!m_psz, "m_psz not deallocated before ~CValue called.");
}
#endif
}
VOID CValue::Init(VALUETYPE type, DWORD value)
{
Assert(m_fInit == FALSE);
m_fInit = TRUE;
SetType(type);
SetPresent(TRUE);
SetInvalidChars(FALSE);
SetEmptyString(FALSE);
if ((GetType() == VALUETYPE_EDIT) ||
(GetType() == VALUETYPE_ENUM) ||
(GetType() == VALUETYPE_KONLY))
{
m_fNumeric = FALSE;
m_psz = NULL;
FromString(NULL);
}
else
{
m_fNumeric = TRUE;
m_dw = value;
}
}
VOID CValue::InitNotPresent(VALUETYPE type)
{
Init(type, 0);
SetPresent(FALSE);
}
VOID CValue::Destroy()
{
AssertSz(m_fInit, "CValue class not Init'ed");
if (!IsNumeric())
{
delete m_psz;
m_psz = NULL;
}
m_dw = NULL; // since all other values are a union, this'll clear
// out everything.
m_fInit = FALSE;
}
// copies into current object
VOID CValue::Copy(CValue *pvSrc)
{
AssertSz(m_fInit, "CValue class not Init'ed");
Assert(pvSrc != NULL);
AssertSz(m_eType == pvSrc->m_eType,
"Can't copy from different value types.");
// Clear out the destination value
Destroy();
AssertSz( ! m_psz, "Memory should have been deallocated by Destroy()");
// Copy contents of source value
*this = *pvSrc;
// Reallocate string
if ( ! pvSrc->IsNumeric())
{
if (pvSrc->m_psz)
{
// allocate and copy string.
m_psz = new WCHAR[lstrlenW(pvSrc->m_psz) + 1];
if (m_psz == NULL)
{
Assert(0);
return;
}
lstrcpyW(m_psz,pvSrc->m_psz);
}
}
}
VOID CValue::SetNumericValue(DWORD dw)
{
Assert(m_fInit);
Assert(m_fNumeric);
switch(m_eType)
{
case VALUETYPE_DWORD:
SetDword(dw);
break;
case VALUETYPE_LONG:
SetLong(dw);
break;
case VALUETYPE_WORD:
Assert(dw <= USHRT_MAX);
SetWord(static_cast<WORD>(dw));
break;
case VALUETYPE_INT:
Assert(dw <= SHRT_MAX);
Assert(dw >= SHRT_MIN);
SetShort(static_cast<short>(dw));
break;
default:
AssertSz(FALSE, "Invalid numeric type for this value");
break;
}
}
BOOL CValue::FromString(const WCHAR * const pszValue)
{
UINT uBase;
PWSTR pszEnd;
PWSTR psz;
WCHAR szTemp[VALUE_SZMAX];
AssertSz(m_fInit, "CValue class not Init'ed");
// Fixup string
if (!pszValue)
{
szTemp[0] = L'\0';
}
else
{
lstrcpynW(szTemp,pszValue, celems(szTemp));
StripSpaces(szTemp);
}
psz = szTemp;
// Get numeric base
uBase = IsHex() ? 16 : 10;
// Initialize to valid
SetInvalidChars(FALSE);
SetEmptyString(FALSE);
if ( ! *psz)
{
SetEmptyString(TRUE);
}
// Convert
switch (GetType())
{
default:
case VALUETYPE_INT:
SetShort((short)wcstol(psz,&pszEnd,uBase));
if (*pszEnd != L'\0')
{
SetInvalidChars(TRUE);
}
break;
case VALUETYPE_LONG:
SetLong(wcstol(psz,&pszEnd,uBase));
if (*pszEnd != L'\0')
{
SetInvalidChars(TRUE);
}
break;
case VALUETYPE_WORD:
SetWord((WORD)wcstoul(psz,&pszEnd,uBase));
if (*pszEnd != L'\0')
{
SetInvalidChars(TRUE);
}
break;
case VALUETYPE_DWORD:
SetDword(wcstoul(psz,&pszEnd,uBase));
if (*pszEnd != L'\0')
{
SetInvalidChars(TRUE);
}
break;
case VALUETYPE_ENUM:
case VALUETYPE_EDIT:
if (m_psz)
{
delete m_psz;
m_psz = NULL;
}
m_psz = new WCHAR[lstrlenW(psz) + 1];
if (m_psz == NULL)
{
return(FALSE);
}
lstrcpyW(m_psz,psz);
break;
case VALUETYPE_KONLY:
break;
}
return TRUE;
}
BOOL CValue::ToString(WCHAR * sz, UINT cch)
{
UINT len;
AssertSz(m_fInit, "CValue class not Init'ed");
Assert(sz != NULL);
switch (GetType())
{
case VALUETYPE_INT:
len = (UINT)wsprintfW(sz,L"%d",GetShort());
Assert(len+1 <= cch); // verify that we allocated enough space
break;
case VALUETYPE_LONG:
len = (UINT)wsprintfW(sz,L"%ld",GetLong());
Assert(len+1 <= cch);
break;
case VALUETYPE_WORD:
if (IsHex()) {
len = (UINT)wsprintfW(sz,L"%-2X",GetWord());
} else {
len = (UINT)wsprintfW(sz,L"%u",GetWord());
}
Assert(len+1 <= cch);
break;
case VALUETYPE_DWORD:
if (IsHex()) {
len = (UINT)wsprintfW(sz,L"%-2lX",GetDword());
} else {
len = (UINT)wsprintfW(sz,L"%lu",GetDword());
}
Assert(len+1 <= cch);
break;
case VALUETYPE_ENUM:
case VALUETYPE_EDIT:
lstrcpynW (sz, m_psz, cch);
break;
case VALUETYPE_KONLY:
Assert(cch >= 2);
lstrcpynW (sz, L"1", cch); // If present, store a "1" in the registry.
break;
}
return TRUE;
}
// Compares the current object to another object
// Return values: 0 = both objs are the same
// <0 = cur obj is less then the other obj
// >0 = cur obj is greater than the other obj
int CValue::Compare(CValue *pv2)
{
AssertSz(m_fInit, "CValue class not Init'ed");
Assert(pv2 != NULL);
Assert(GetType() == pv2->GetType());
// Present/not present (present is greater than not present)
if (!IsPresent() && !pv2->IsPresent())
{
return 0;
}
if (!IsPresent() && pv2->IsPresent())
{
return -1;
}
if (IsPresent() && !pv2->IsPresent())
{
return 1;
}
// Compare
switch (GetType())
{
case VALUETYPE_INT:
if (GetShort() == pv2->GetShort())
{
return 0;
}
return (GetShort() < pv2->GetShort()) ? -1 : 1;
case VALUETYPE_LONG:
if (GetLong() == pv2->GetLong())
{
return 0;
}
return (GetLong() < pv2->GetLong())? -1 : 1;
case VALUETYPE_WORD:
if (GetWord() == pv2->GetWord())
{
return 0;
}
return (GetWord() < pv2->GetWord())? -1 : 1;
case VALUETYPE_DWORD:
if (GetDword() == pv2->GetDword())
{
return 0;
}
return (GetDword() < pv2->GetDword())? -1 : 1;
case VALUETYPE_ENUM:
case VALUETYPE_EDIT:
if ((GetPsz() != NULL) && (pv2->GetPsz() != NULL))
{
return lstrcmpW(GetPsz(),pv2->GetPsz());
}
else
{
return -2; // REVIEW: what does -2 mean?
}
case VALUETYPE_KONLY:
return 1;
default:
Assert(FALSE);
return 1; // to stop compiler warning.
}
}
// if false, then value doesn't change.
BOOL CValue::FLoadFromRegistry(HKEY hk, const WCHAR * pszValueName, HKEY hkParam /* = INVALID_HANDLE_VALUE */)
{
DWORD cbBuf;
WCHAR szBuf[VALUE_SZMAX];
DWORD dwType;
HRESULT hr = S_OK;
HKEY hkTemp;
AssertSz(m_fInit, "CValue class not Init'ed");
Assert(hk);
Assert(pszValueName);
// determine base
SetHex(FALSE);
if (hkParam != (HKEY)INVALID_HANDLE_VALUE)
hkTemp = hkParam;
else
hkTemp = hk;
if (Reg_QueryInt(hkTemp, c_szRegParamBase,10) == 16)
{
SetHex(TRUE);
}
cbBuf = sizeof(szBuf);
hr = HrRegQueryValueEx(hk,pszValueName,&dwType,(BYTE*)szBuf,&cbBuf);
if (SUCCEEDED(hr))
{
AssertSz(REG_SZ == dwType,
"Expecting REG_SZ, but got something else.");
}
if (FAILED(hr) || !szBuf[0])
{
return FALSE;
}
m_fPresent = TRUE;
return FromString(szBuf);
}
BOOL CValue::FSaveToRegistry(HKEY hk, const WCHAR * pszValueName)
{
DWORD cbBuf;
WCHAR szBuf[VALUE_SZMAX];
AssertSz(m_fInit, "CValue class not Init'ed");
Assert(hk);
Assert(pszValueName);
if (!IsPresent())
{
RegDeleteValue(hk,pszValueName);
return TRUE;
}
ToString(szBuf,celems(szBuf));
cbBuf = CbOfSzAndTerm(szBuf);
return (RegSetValueEx(
hk,
pszValueName,
NULL,
REG_SZ,
(LPBYTE)
szBuf,
cbBuf)
== ERROR_SUCCESS);
}
int CValue::GetNumericValueAsSignedInt()
{
Assert(m_fInit);
Assert(m_fPresent);
Assert(m_fNumeric);
int nret = 0;
switch (m_eType)
{
case VALUETYPE_DWORD:
nret = GetDword();
break;
case VALUETYPE_LONG:
nret = GetLong();
break;
case VALUETYPE_WORD:
nret = GetWord();
break;
case VALUETYPE_INT:
nret = GetShort();
break;
default:
Assert("Hit default case in GetNumericValueAsSignedInt");
break;
}
return nret;
}
DWORD CValue::GetNumericValueAsDword()
{
AssertH(m_fInit);
AssertH(m_fPresent);
AssertH(m_fNumeric);
DWORD dwret = 0;
switch (m_eType)
{
case VALUETYPE_DWORD:
dwret = GetDword();
break;
case VALUETYPE_LONG:
dwret = GetLong();
break;
case VALUETYPE_WORD:
dwret = GetWord();
break;
case VALUETYPE_INT:
dwret = GetShort();
break;
default:
Assert("Hit default case in GetNumericValueAsSignedInt");
break;
}
return dwret;
}