windows-nt/Source/XPSP1/NT/enduser/windows.com/wuv3/wudetect/utils2.cpp

430 lines
13 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//#include <nt.h>
//#include <ntrtl.h>
//#include <nturtl.h>
//#include <windows.h>
//#include <objbase.h>
//#include <inseng.h>
//#include "utils2.h"
#include "wudetect.h"
/////////////////////////////////////////////////////////////////////////////
// dwParseValue
//
// Parses out the registry key name, value, and type that needs to
// be opened to determine the installation status of the component.
/////////////////////////////////////////////////////////////////////////////
//
// Class CExpressionParser
// Function dwParseValue
//---------------------------------------------------------------------------
//
// Return Value --- DWORD, if the function succeeded, return ERROR_SUCCESS
// if the function failed, return ERROR_BADKEY
// Parameters
// DWORD iToken --- [IN] Index Number of Field to looking for
// TCHAR* szBuf --- [IN] String to search for
// TargetRegValue& targerValue --- [OUT] two (three) fields will be set if function succeeded,
// szName field will be set to the Name in the String token
// szType field will be set to either REG_DWORD, REG_SZ_TYPE or REG_BINARY_TYPE depends on the String Token
// if szType is REG_DWORD, the dw field will be set to the value depends on the String
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Modified by RogerJ, 03/08/00
// Original Creator Unknown
// Modification --- UNICODE and Win64 ready
//
//////////////////////////////////////////////////////////////////////////////////////////////////
DWORD CExpressionParser::dwParseValue(DWORD iToken, TCHAR * szBuf, TargetRegValue & targetValue)
{
DWORD dwStatus = ERROR_BADKEY;
TCHAR szType[MAX_PATH]; // BUGBUG - get real value
TCHAR szValue[MAX_PATH]; // BUGBUG - get real value
// get the data type
if ( (GetStringField2(szBuf, iToken, targetValue.szName, sizeof(targetValue.szName)/sizeof(TCHAR)) != 0) &&
(GetStringField2(szBuf, ++iToken, szType, sizeof(szType)/sizeof(TCHAR)) != 0) )
{
if ( lstrcmpi(REG_NONE_TYPE, szType) == 0 )
{
targetValue.type = REG_NONE;
dwStatus = ERROR_SUCCESS;
}
else
{
if ( GetStringField2(szBuf, ++iToken, szValue, sizeof(szValue)/sizeof(TCHAR)) != 0 )
{
if ( lstrcmpi(REG_DWORD_TYPE, szType) == 0 )
{
targetValue.type = REG_DWORD;
targetValue.dw = _ttol(szValue);
dwStatus = ERROR_SUCCESS;
}
else if ( lstrcmpi(REG_SZ_TYPE, szType) == 0 )
{
targetValue.type = REG_SZ;
lstrcpy(targetValue.sz, szValue);
dwStatus = ERROR_SUCCESS;
}
else if ( lstrcmpi(REG_BINARY_TYPE, szType) == 0 )
{
targetValue.type = REG_BINARY;
lstrcpy(targetValue.sz, szValue);
dwStatus = ERROR_SUCCESS;
}
}
}
}
return dwStatus;
}
/////////////////////////////////////////////////////////////////////////////
// fCompareVersion
/////////////////////////////////////////////////////////////////////////////
//
// Class CExpressionParser
// Function fCompareVersion
//--------------------------------------------------------------------------
// Return Value --- TRUE if value equals, FALSE if value does not equal or
// no Comparison type specified exist
// Parameter
// DWORD dwVer1 --- [IN] version number of first value
// DWORD dwBuild1 --- [IN] build number of first value
// enumToken enComparisonToken --- [IN] reason to compare
// DWORD dwVer2 --- [IN] version number of second value
// DWORD dwBuild2 --- [IN] build number of second value
/////////////////////////////////////////////////////////////////////////////
//
// Original Creator Unknown
// No modification made at 03/08/00 by RogerJ
//
////////////////////////////////////////////////////////////////////////////
bool CExpressionParser::fCompareVersion(IN DWORD dwVer1,
IN DWORD dwBuild1,
IN enumToken enComparisonToken,
IN DWORD dwVer2,
IN DWORD dwBuild2)
{
bool fResult = false;
switch ( enComparisonToken )
{
case COMP_EQUALS:
fResult = (dwVer1 == dwVer2) && (dwBuild1 == dwBuild2);
break;
case COMP_NOT_EQUALS:
fResult = (dwVer1 != dwVer2) || (dwBuild1 != dwBuild2);
break;
case COMP_LESS_THAN:
fResult = (dwVer1 < dwVer2) || ((dwVer1 == dwVer2) && (dwBuild1 < dwBuild2));
break;
case COMP_LESS_THAN_EQUALS:
fResult = (dwVer1 < dwVer2) || ((dwVer1 == dwVer2) && (dwBuild1 <= dwBuild2));
break;
case COMP_GREATER_THAN:
fResult = (dwVer1 > dwVer2) || ((dwVer1 == dwVer2) && (dwBuild1 > dwBuild2));
break;
case COMP_GREATER_THAN_EQUALS:
fResult = (dwVer1 > dwVer2) || ((dwVer1 == dwVer2) && (dwBuild1 >= dwBuild2));
break;
}
return fResult;
}
/////////////////////////////////////////////////////////////////////////////
// fMapRegRoot
// Determines the registry root (HKLM, HKCU, etc) that the key lies under.
/////////////////////////////////////////////////////////////////////////////
//
// Function fMapRegRoot
//---------------------------------------------------------------------------
//
// Return Value --- TRUE if function succeeded, FALSE if can't find correct registry root
// Parameter
// TCHAR* pszBuf --- [IN] String to search for
// DWORD index --- [IN] Index Number of Field to looking for
// HKEY* phKey --- [OUT] key value found
/////////////////////////////////////////////////////////////////////////////
//
// Modified by RogerJ, 03/08/00
// Original Creator Unkown
// Modification made --- UNICODE and Win64 Ready
//
/////////////////////////////////////////////////////////////////////////////
bool fMapRegRoot(TCHAR *pszBuf, DWORD index, HKEY *phKey)
{
TCHAR szRootType[MAX_PATH];
if ( GetStringField2(pszBuf, (UINT)index, szRootType, sizeof(szRootType)/sizeof(TCHAR)) == 0 )
return false;
if ( lstrcmpi(HKEY_LOCAL_MACHINE_ROOT, szRootType) == 0 )
{
*phKey = HKEY_LOCAL_MACHINE;
}
else if ( lstrcmpi(HKEY_CURRENT_USER_ROOT, szRootType) == 0 )
{
*phKey = HKEY_CURRENT_USER;
}
else if ( lstrcmpi(HKEY_CLASSES_ROOT_ROOT, szRootType) == 0 )
{
*phKey = HKEY_CLASSES_ROOT;
}
else if ( lstrcmpi(HKEY_CURRENT_CONFIG_ROOT, szRootType) == 0 )
{
*phKey = HKEY_CURRENT_CONFIG;
}
else if ( lstrcmpi(HKEY_USERS_ROOT, szRootType) == 0 )
{
*phKey = HKEY_USERS;
}
else if ( lstrcmpi(HKEY_PERFORMANCE_DATA_ROOT, szRootType) == 0 )
{
*phKey = HKEY_PERFORMANCE_DATA;
}
else if ( lstrcmpi(HKEY_DYN_DATA_ROOT, szRootType) == 0 )
{
*phKey = HKEY_DYN_DATA;
}
else return false;
return true;
}
//--------------------------------------------------------------------------
// GetStringField2
//--------------------------------------------------------------------------
//
// Function GetStringField2
//--------------------------------------------------------------------------
//
// Return Value: DWORD, the number of TCHAR copied, not including the NULL character
// Parameters:
// LPTSTR szStr --- [IN] String to search for
// UINT uField --- [IN] Index Number of Field to looking for
// LPTSTR szBuf --- [IN,OUT] String buffer to copy to
// UINT cBufSize --- [IN] Size of szBuf in TCHAR
//////////////////////////////////////////////////////////////////////////////
//
// Modified by RogerJ, 03/08/00
// Original Creator Unknown
// Modification made --- UNICODE and Win64 Compatbility
//
//////////////////////////////////////////////////////////////////////////////
#define WHITESPACE TEXT(" \t")
DWORD GetStringField2(LPTSTR szStr, UINT uField, LPTSTR szBuf, UINT cBufSize)
{
LPTSTR pszBegin = szStr;
LPTSTR pszEnd;
UINT i;
DWORD dwToCopy;
if ( (cBufSize == 0) || (szStr == NULL) || (szBuf == NULL) )
{
return 0;
}
szBuf[0] = '\0';
// look for fields based on commas but handle quotes.
// check the ith Field, each field separated by either quote or comma
for (i = 0 ;i < uField; i++ )
{
// skip spaces
pszBegin += _tcsspn(pszBegin, WHITESPACE);
// handle quotes
if ( *pszBegin == '"' )
{
pszBegin = _tcschr(++pszBegin, '"');
if ( pszBegin == NULL )
{
return 0; // invalid string
}
pszBegin++; // skip trailing quote
// find start of next string
pszBegin += _tcsspn(pszBegin, WHITESPACE);
if ( *pszBegin != ',' )
{
return 0;
}
}
else
{
pszBegin = _tcschr(++pszBegin, ',');
if ( pszBegin == NULL )
{
return 0; // field isn't here
}
}
pszBegin++;
}
// pszBegin points to the start of the desired string.
// skip spaces
pszBegin += _tcsspn(pszBegin, WHITESPACE);
// handle quotes
if ( *pszBegin == '"' )
{
pszEnd = _tcschr(++pszBegin, '"');
if ( pszEnd == NULL )
{
return 0; // invalid string
}
}
else
{
pszEnd = pszBegin + 1 + _tcscspn(pszBegin + 1, TEXT(","));
while ( (pszEnd > pszBegin) &&
((*(pszEnd - 1) == ' ') || (*(pszEnd - 1) == '\t')) )
{
pszEnd--;
}
}
// length of buffer to copy should never exceed 32 bits.
dwToCopy = (DWORD)(pszEnd - pszBegin + 1);
if ( dwToCopy > cBufSize )
{
dwToCopy = cBufSize;
}
lstrcpyn(szBuf, pszBegin, dwToCopy);
return dwToCopy - 1;
}
//--------------------------------------------------------------------------
// GetIntField
//--------------------------------------------------------------------------
//
// Function GetIntField
//--------------------------------------------------------------------------
//
// Return Value: DWORD, Integer value of wanted field
// Parameters:
// LPTSTR szStr --- [IN] String to search for
// UINT uField --- [IN] Index Number of Field to looking for
// DWORD dwDefault --- [IN] default value
////////////////////////////////////////////////////////////////////////////
//
// Modified by RogerJ, 03/08/00
// Original Creator Unknown
// Modification made --- UNICODE and Win64 compatibility
// NOTE --- NOT used in current version
//
////////////////////////////////////////////////////////////////////////////
#if 0 // not used yet
DWORD GetIntField(LPTSTR szStr, UINT uField, DWORD dwDefault)
{
TCHAR szNumBuf[16];
if(GetStringField(szStr, uField, szNumBuf, sizeof(szNumBuf)/sizeof(TCHAR)) == 0)
return dwDefault;
else
return _ttol(szNumBuf);
}
#endif
//--------------------------------------------------------------------------
// ConvertVersionStrToDwords
//--------------------------------------------------------------------------
//
// Function ConvertVersionStrToDwords
//--------------------------------------------------------------------------
//
// Return Value --- no return value
// Parameter
// LPTSTR pszVer --- [IN] input string containing the version and build information
// LPDWORD pdwVer --- [OUT] the version value extracted from pszVer
// LPDWORD pdwBuild --- [OUT] the build value extracted from pszVer
////////////////////////////////////////////////////////////////////////////
//
// Modified by RogerJ, 03/08/00
// Original Creator Unknown
// Modification --- UNICODE and Win64 ready
// NOTE --- NOT used in current version
//
////////////////////////////////////////////////////////////////////////////
#if 0 // not used yet
void ConvertVersionStrToDwords(LPTSTR pszVer, LPDWORD pdwVer, LPDWORD pdwBuild)
{
DWORD dwTemp1,dwTemp2;
dwTemp1 = GetIntField(pszVer, 0, 0);
dwTemp2 = GetIntField(pszVer, 1, 0);
*pdwVer = (dwTemp1 << 16) + dwTemp2;
dwTemp1 = GetIntField(pszVer, 2, 0);
dwTemp2 = GetIntField(pszVer, 3, 0);
*pdwBuild = (dwTemp1 << 16) + dwTemp2;
}
#endif
//--------------------------------------------------------------------------
// ConvertDotVersionStrToDwords
//--------------------------------------------------------------------------
//
// Function fConvertDotVersionStrToDwords
//--------------------------------------------------------------------------
//
// Return Value --- always true
// Parameter
// LPTSTR pszVer --- [IN] input version string, should have the format
// of x.x.x.x
// LPDWORD pdwVer --- [OUT] version number extracted from pszVer
// LPDWORD pdwBuild --- [OUT] build number extracted from pszVer
//
////////////////////////////////////////////////////////////////////////////
//
// Modified by RogerJ, 03/08/00
// Original Creator Unknown
// Modification --- UNICODE and Win64 ready
//
////////////////////////////////////////////////////////////////////////////
bool fConvertDotVersionStrToDwords(LPTSTR pszVer, LPDWORD pdwVer, LPDWORD pdwBuild)
{
DWORD grVerFields[4] = {0,0,0,0};
TCHAR *pch = pszVer;
grVerFields[0] = _ttol(pch);
for ( int index = 1; index < 4; index++ )
{
while ( IsDigit(*pch) && (*pch != '\0') )
pch++;
if ( *pch == '\0' )
break;
pch++;
grVerFields[index] = _ttol(pch);
}
*pdwVer = (grVerFields[0] << 16) + grVerFields[1];
*pdwBuild = (grVerFields[2] << 16) + grVerFields[3];
return true;
}