📄 statreg.h
字号:
inline CRegParser::CRegParser(CRegObject* pRegObj)
{
m_pRegObj = pRegObj;
m_pchCur = NULL;
}
inline BOOL CRegParser::IsSpace(TCHAR ch)
{
switch (ch)
{
case _T(' '):
case _T('\t'):
case _T('\r'):
case _T('\n'):
return TRUE;
}
return FALSE;
}
inline void CRegParser::SkipWhiteSpace()
{
while(IsSpace(*m_pchCur))
m_pchCur = CharNext(m_pchCur);
}
inline HRESULT CRegParser::NextToken(LPTSTR szToken)
{
USES_CONVERSION;
SkipWhiteSpace();
// NextToken cannot be called at EOS
if (NULL == *m_pchCur)
return GenerateError(E_ATL_UNEXPECTED_EOS);
// handle quoted value / key
if (chQuote == *m_pchCur)
{
LPCTSTR szOrig = szToken;
m_pchCur = CharNext(m_pchCur);
while (NULL != *m_pchCur && !EndOfVar())
{
if (chQuote == *m_pchCur) // If it is a quote that means we must skip it
m_pchCur = CharNext(m_pchCur);
LPTSTR pchPrev = m_pchCur;
m_pchCur = CharNext(m_pchCur);
if (szToken + sizeof(WORD) >= MAX_VALUE + szOrig)
return GenerateError(E_ATL_VALUE_TOO_LARGE);
for (int i = 0; pchPrev+i < m_pchCur; i++, szToken++)
*szToken = *(pchPrev+i);
}
if (NULL == *m_pchCur)
{
ATLTRACE2(atlTraceRegistrar, 0, _T("NextToken : Unexpected End of File\n"));
return GenerateError(E_ATL_UNEXPECTED_EOS);
}
*szToken = NULL;
m_pchCur = CharNext(m_pchCur);
}
else
{ // Handle non-quoted ie parse up till first "White Space"
while (NULL != *m_pchCur && !IsSpace(*m_pchCur))
{
LPTSTR pchPrev = m_pchCur;
m_pchCur = CharNext(m_pchCur);
for (int i = 0; pchPrev+i < m_pchCur; i++, szToken++)
*szToken = *(pchPrev+i);
}
*szToken = NULL;
}
return S_OK;
}
inline HRESULT CRegParser::AddValue(CRegKey& rkParent,LPCTSTR szValueName, LPTSTR szToken)
{
USES_CONVERSION;
HRESULT hr;
TCHAR szTypeToken[MAX_TYPE];
VARTYPE vt;
LONG lRes = ERROR_SUCCESS;
UINT nIDRes = 0;
if (FAILED(hr = NextToken(szTypeToken)))
return hr;
if (!VTFromRegType(szTypeToken, vt))
{
ATLTRACE2(atlTraceRegistrar, 0, _T("%s Type not supported\n"), szTypeToken);
return GenerateError(E_ATL_TYPE_NOT_SUPPORTED);
}
TCHAR szValue[MAX_VALUE];
SkipWhiteSpace();
if (FAILED(hr = NextToken(szValue)))
return hr;
ULONG ulVal;
switch (vt)
{
case VT_BSTR:
lRes = rkParent.SetValue(szValue, szValueName);
ATLTRACE2(atlTraceRegistrar, 2, _T("Setting Value %s at %s\n"), szValue, !szValueName ? _T("default") : szValueName);
break;
case VT_UI4:
VarUI4FromStr(T2OLE(szValue), 0, 0, &ulVal);
lRes = rkParent.SetValue(ulVal, szValueName);
ATLTRACE2(atlTraceRegistrar, 2, _T("Setting Value %d at %s\n"), ulVal, !szValueName ? _T("default") : szValueName);
break;
case VT_UI1:
{
int cbValue = lstrlen(szValue);
if (cbValue & 0x00000001)
{
ATLTRACE2(atlTraceRegistrar, 0, _T("Binary Data does not fall on BYTE boundries\n"));
return E_FAIL;
}
int cbValDiv2 = cbValue/2;
BYTE* rgBinary = (BYTE*)_alloca(cbValDiv2*sizeof(BYTE));
memset(rgBinary, 0, cbValDiv2);
if (rgBinary == NULL)
return E_FAIL;
for (int irg = 0; irg < cbValue; irg++)
rgBinary[(irg/2)] |= (ChToByte(szValue[irg])) << (4*(1 - (irg & 0x00000001)));
lRes = RegSetValueEx(rkParent, szValueName, 0, REG_BINARY, rgBinary, cbValDiv2);
break;
}
}
if (ERROR_SUCCESS != lRes)
{
nIDRes = E_ATL_VALUE_SET_FAILED;
hr = HRESULT_FROM_WIN32(lRes);
}
if (FAILED(hr = NextToken(szToken)))
return hr;
return S_OK;
}
inline BOOL CRegParser::CanForceRemoveKey(LPCTSTR szKey)
{
for (int iNoDel = 0; iNoDel < cbNeverDelete; iNoDel++)
if (!lstrcmpi(szKey, rgszNeverDelete[iNoDel]))
return FALSE; // We cannot delete it
return TRUE;
}
inline BOOL CRegParser::HasSubKeys(HKEY hkey)
{
DWORD cbSubKeys = 0;
if (FAILED(RegQueryInfoKey(hkey, NULL, NULL, NULL,
&cbSubKeys, NULL, NULL,
NULL, NULL, NULL, NULL, NULL)))
{
ATLTRACE2(atlTraceRegistrar, 0, _T("Should not be here!!\n"));
ATLASSERT(FALSE);
return FALSE;
}
return cbSubKeys > 0;
}
inline BOOL CRegParser::HasValues(HKEY hkey)
{
DWORD cbValues = 0;
LONG lResult = RegQueryInfoKey(hkey, NULL, NULL, NULL,
NULL, NULL, NULL,
&cbValues, NULL, NULL, NULL, NULL);
if (ERROR_SUCCESS != lResult)
{
ATLTRACE2(atlTraceRegistrar, 0, _T("RegQueryInfoKey Failed "));
ATLASSERT(FALSE);
return FALSE;
}
if (1 == cbValues)
{
DWORD cbMaxName= MAX_VALUE;
TCHAR szValueName[MAX_VALUE];
// Check to see if the Value is default or named
lResult = RegEnumValue(hkey, 0, szValueName, &cbMaxName, NULL, NULL, NULL, NULL);
if (ERROR_SUCCESS == lResult && (szValueName[0] != NULL))
return TRUE; // Named Value means we have a value
return FALSE;
}
return cbValues > 0; // More than 1 means we have a non-default value
}
inline HRESULT CRegParser::SkipAssignment(LPTSTR szToken)
{
HRESULT hr;
TCHAR szValue[MAX_VALUE];
if (*szToken == chEquals)
{
if (FAILED(hr = NextToken(szToken)))
return hr;
// Skip assignment
SkipWhiteSpace();
if (FAILED(hr = NextToken(szValue)))
return hr;
if (FAILED(hr = NextToken(szToken)))
return hr;
}
return S_OK;
}
inline HRESULT CRegParser::PreProcessBuffer(LPTSTR lpszReg, LPTSTR* ppszReg)
{
USES_CONVERSION;
ATLASSERT(lpszReg != NULL);
ATLASSERT(ppszReg != NULL);
*ppszReg = NULL;
int nSize = lstrlen(lpszReg)*2;
CParseBuffer pb(nSize);
if (pb.p == NULL)
return E_OUTOFMEMORY;
m_pchCur = lpszReg;
HRESULT hr = S_OK;
while (*m_pchCur != NULL) // look for end
{
if (*m_pchCur == _T('%'))
{
m_pchCur = CharNext(m_pchCur);
if (*m_pchCur == _T('%'))
pb.AddChar(m_pchCur);
else
{
LPTSTR lpszNext = StrChr(m_pchCur, _T('%'));
if (lpszNext == NULL)
{
ATLTRACE2(atlTraceRegistrar, 0, _T("Error no closing % found\n"));
hr = GenerateError(E_ATL_UNEXPECTED_EOS);
break;
}
int nLength = lpszNext - m_pchCur;
if (nLength > 31)
{
hr = E_FAIL;
break;
}
TCHAR buf[32];
lstrcpyn(buf, m_pchCur, nLength+1);
LPCOLESTR lpszVar = m_pRegObj->StrFromMap(buf);
if (lpszVar == NULL)
{
hr = GenerateError(E_ATL_NOT_IN_MAP);
break;
}
pb.AddString(lpszVar);
while (m_pchCur != lpszNext)
m_pchCur = CharNext(m_pchCur);
}
}
else
pb.AddChar(m_pchCur);
m_pchCur = CharNext(m_pchCur);
}
pb.AddChar(m_pchCur);
if (SUCCEEDED(hr))
*ppszReg = pb.Detach();
return hr;
}
inline HRESULT CRegParser::RegisterBuffer(LPTSTR szBuffer, BOOL bRegister)
{
TCHAR szToken[MAX_VALUE];
HRESULT hr = S_OK;
LPTSTR szReg;
hr = PreProcessBuffer(szBuffer, &szReg);
if (FAILED(hr))
return hr;
#ifdef _DEBUG
OutputDebugString(szReg); //would call ATLTRACE but szReg is > 512 bytes
OutputDebugString(_T("\n"));
#endif //_DEBUG
m_pchCur = szReg;
// Preprocess szReg
while (NULL != *m_pchCur)
{
if (FAILED(hr = NextToken(szToken)))
break;
HKEY hkBase;
if ((hkBase = HKeyFromString(szToken)) == NULL)
{
ATLTRACE2(atlTraceRegistrar, 0, _T("HKeyFromString failed on %s\n"), szToken);
hr = GenerateError(E_ATL_BAD_HKEY);
break;
}
if (FAILED(hr = NextToken(szToken)))
break;
if (chLeftBracket != *szToken)
{
ATLTRACE2(atlTraceRegistrar, 0, _T("Syntax error, expecting a {, found a %s\n"), szToken);
hr = GenerateError(E_ATL_MISSING_OPENKEY_TOKEN);
break;
}
if (bRegister)
{
LPTSTR szRegAtRegister = m_pchCur;
hr = RegisterSubkeys(szToken, hkBase, bRegister);
if (FAILED(hr))
{
ATLTRACE2(atlTraceRegistrar, 0, _T("Failed to register, cleaning up!\n"));
m_pchCur = szRegAtRegister;
RegisterSubkeys(szToken, hkBase, FALSE);
break;
}
}
else
{
if (FAILED(hr = RegisterSubkeys(szToken, hkBase, bRegister)))
break;
}
SkipWhiteSpace();
}
CoTaskMemFree(szReg);
return hr;
}
inline HRESULT CRegParser::RegisterSubkeys(LPTSTR szToken, HKEY hkParent, BOOL bRegister, BOOL bRecover)
{
CRegKey keyCur;
LONG lRes;
LPTSTR szKey = NULL;
BOOL bDelete = TRUE;
BOOL bInRecovery = bRecover;
HRESULT hr = S_OK;
ATLTRACE2(atlTraceRegistrar, 2, _T("Num Els = %d\n"), cbNeverDelete);
if (FAILED(hr = NextToken(szToken)))
return hr;
while (*szToken != chRightBracket) // Continue till we see a }
{
BOOL bTokenDelete = !lstrcmpi(szToken, szDelete);
if (!lstrcmpi(szToken, szForceRemove) || bTokenDelete)
{
if (FAILED(hr = NextToken(szToken)))
break;
if (bRegister)
{
CRegKey rkForceRemove;
if (StrChr(szToken, chDirSep) != NULL)
return GenerateError(E_ATL_COMPOUND_KEY);
if (CanForceRemoveKey(szToken))
{
rkForceRemove.Attach(hkParent);
rkForceRemove.RecurseDeleteKey(szToken);
rkForceRemove.Detach();
}
if (bTokenDelete)
{
if (FAILED(hr = NextToken(szToken)))
break;
if (FAILED(hr = SkipAssignment(szToken)))
break;
goto EndCheck;
}
}
}
if (!lstrcmpi(szToken, szNoRemove))
{
bDelete = FALSE; // set even for register
if (FAILED(hr = NextToken(szToken)))
break;
}
if (!lstrcmpi(szToken, szValToken)) // need to add a value to hkParent
{
TCHAR szValueName[_MAX_PATH];
if (FAILED(hr = NextToken(szValueName)))
break;
if (FAILED(hr = NextToken(szToken)))
break;
if (*szToken != chEquals)
return GenerateError(E_ATL_EXPECTING_EQUAL);
if (bRegister)
{
CRegKey rk;
rk.Attach(hkParent);
hr = AddValue(rk, szValueName, szToken);
rk.Detach();
if (FAILED(hr))
return hr;
goto EndCheck;
}
else
{
if (!bRecover)
{
ATLTRACE2(atlTraceRegistrar, 1, _T("Deleting %s\n"), szValueName);
CRegKey rkParent;
rkParent.Attach(hkParent);
rkParent.DeleteValue(szValueName);
rkParent.Detach();
}
if (FAILED(hr = SkipAssignment(szToken)))
break;
continue; // can never have a subkey
}
}
if (StrChr(szToken, chDirSep) != NULL)
return GenerateError(E_ATL_COMPOUND_KEY);
if (bRegister)
{
lRes = keyCur.Open(hkParent, szToken, KEY_ALL_ACCESS);
if (ERROR_SUCCESS != lRes)
{
// Failed all access try read only
lRes = keyCur.Open(hkParent, szToken, KEY_READ);
if (ERROR_SUCCESS != lRes)
{
// Finally try creating it
ATLTRACE2(atlTraceRegistrar, 2, _T("Creating key %s\n"), szToken);
lRes = keyCur.Create(hkParent, szToken);
if (ERROR_SUCCESS != lRes)
return GenerateError(E_ATL_CREATE_KEY_FAILED);
}
}
if (FAILED(hr = NextToken(szToken)))
break;
if (*szToken == chEquals)
{
if (FAILED(hr = AddValue(keyCur, NULL, szToken))) // NULL == default
break;
}
}
else
{
if (!bRecover && keyCur.Open(hkParent, szToken, KEY_READ) != ERROR_SUCCESS)
bRecover = TRUE;
// TRACE out Key open status and if in recovery mode
#ifdef _DEBUG
if (!bRecover)
ATLTRACE2(atlTraceRegistrar, 1, _T("Opened Key %s\n"), szToken);
else
ATLTRACE2(atlTraceRegistrar, 0, _T("Ignoring Open key on %s : In Recovery mode\n"), szToken);
#endif //_DEBUG
// Remember Subkey
if (szKey == NULL)
szKey = (LPTSTR)_alloca(sizeof(TCHAR)*_MAX_PATH);
lstrcpyn(szKey, szToken, _MAX_PATH);
// If in recovery mode
if (bRecover || HasSubKeys(keyCur) || HasValues(keyCur))
{
if (FAILED(hr = NextToken(szToken)))
break;
if (FAILED(hr = SkipAssignment(szToken)))
break;
if (*szToken == chLeftBracket)
{
if (FAILED(hr = RegisterSubkeys(szToken, keyCur.m_hKey, bRegister, bRecover)))
break;
if (bRecover) // Turn off recovery if we are done
{
bRecover = bInRecovery;
ATLTRACE2(atlTraceRegistrar, 0, _T("Ending Recovery Mode\n"));
if (FAILED(hr = NextToken(szToken)))
break;
if (FAILED(hr = SkipAssignment(szToken)))
break;
continue;
}
}
if (!bRecover && HasSubKeys(keyCur))
{
// See if the KEY is in the NeverDelete list and if so, don't
if (CanForceRemoveKey(szKey))
{
ATLTRACE2(atlTraceRegistrar, 0, _T("Deleting non-empty subkey %s by force\n"), szKey);
keyCur.RecurseDeleteKey(szKey);
}
if (FAILED(hr = NextToken(szToken)))
break;
continue;
}
if (bRecover)
continue;
}
if (!bRecover && keyCur.Close() != ERROR_SUCCESS)
return GenerateError(E_ATL_CLOSE_KEY_FAILED);
if (!bRecover && bDelete)
{
ATLTRACE2(atlTraceRegistrar, 0, _T("Deleting Key %s\n"), szKey);
CRegKey rkParent;
rkParent.Attach(hkParent);
rkParent.DeleteSubKey(szKey);
rkParent.Detach();
}
if (FAILED(hr = NextToken(szToken)))
break;
if (FAILED(hr = SkipAssignment(szToken)))
break;
}
EndCheck:
if (bRegister)
{
if (*szToken == chLeftBracket && lstrlen(szToken) == 1)
{
if (FAILED(hr = RegisterSubkeys(szToken, keyCur.m_hKey, bRegister, FALSE)))
break;
if (FAILED(hr = NextToken(szToken)))
break;
}
}
}
return hr;
}
}; //namespace ATL
#endif //__STATREG_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -