525 lines
12 KiB
C++
525 lines
12 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1997.
|
||
|
//
|
||
|
// File: K K U T I L S . C P P
|
||
|
//
|
||
|
// Contents: Misc. helper functions
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// Author: kumarp 14 Jan 1997
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "pch.h"
|
||
|
#pragma hdrstop
|
||
|
#include "kkutils.h"
|
||
|
#include "ncreg.h"
|
||
|
|
||
|
extern const WCHAR c_szRegKeyServices[];
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: AddOnlyOnceToStringList
|
||
|
//
|
||
|
// Purpose: Add the specified string to the list if it is not present
|
||
|
// in that list
|
||
|
//
|
||
|
// Arguments:
|
||
|
// psl [in] list of strings
|
||
|
// pszString [in] string to add
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
// Author: kumarp 23-December-97
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
void AddOnlyOnceToStringList(IN TStringList* psl, IN PCWSTR pszString)
|
||
|
{
|
||
|
AssertValidReadPtr(psl);
|
||
|
AssertValidReadPtr(pszString);
|
||
|
|
||
|
if (!FIsInStringList(*psl, pszString))
|
||
|
{
|
||
|
AddAtEndOfStringList(*psl, pszString);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ConvertDelimitedListToStringList
|
||
|
//
|
||
|
// Purpose: Convert a delimited list to a TStringList
|
||
|
//
|
||
|
// Arguments:
|
||
|
// strDelimitedList [in] delimited list
|
||
|
// chDelimiter [in] delimiter
|
||
|
// slList [out] list of string items
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
// Author: kumarp 23-December-97
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
void ConvertDelimitedListToStringList(IN const tstring& strDelimitedList,
|
||
|
IN WCHAR chDelimiter,
|
||
|
OUT TStringList &slList)
|
||
|
{
|
||
|
PCWSTR pszDelimitedList = strDelimitedList.c_str();
|
||
|
DWORD i=0, dwStart;
|
||
|
|
||
|
// should this be EraseAndDeleteAll() ??
|
||
|
//EraseAll(&slList);
|
||
|
EraseAndDeleteAll(&slList);
|
||
|
tstring strTemp;
|
||
|
DWORD dwNumChars;
|
||
|
|
||
|
// the two spaces are intentional
|
||
|
static WCHAR szCharsToSkip[] = L" \t";
|
||
|
szCharsToSkip[0] = chDelimiter;
|
||
|
|
||
|
while (pszDelimitedList[i])
|
||
|
{
|
||
|
dwStart = i;
|
||
|
while (pszDelimitedList[i] &&
|
||
|
!wcschr(szCharsToSkip, pszDelimitedList[i]))
|
||
|
{
|
||
|
++i;
|
||
|
}
|
||
|
|
||
|
// if each item is enclosed in quotes. strip the quotes
|
||
|
dwNumChars = i - dwStart;
|
||
|
if (pszDelimitedList[dwStart] == '"')
|
||
|
{
|
||
|
dwStart++;
|
||
|
dwNumChars -= 2;
|
||
|
}
|
||
|
|
||
|
strTemp = strDelimitedList.substr(dwStart, dwNumChars);
|
||
|
slList.insert(slList.end(), new tstring(strTemp));
|
||
|
|
||
|
// skip spaces and delimiter
|
||
|
//
|
||
|
while (pszDelimitedList[i] &&
|
||
|
wcschr(szCharsToSkip, pszDelimitedList[i]))
|
||
|
{
|
||
|
++i;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ConvertCommaDelimitedListToStringList
|
||
|
//
|
||
|
// Purpose: Convert a comma delimited list to a TStringList
|
||
|
//
|
||
|
// Arguments:
|
||
|
// strDelimitedList [in] comma delimited list
|
||
|
// slList [out] list of string items
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
// Author: kumarp 23-December-97
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
void ConvertCommaDelimitedListToStringList(IN const tstring& strDelimitedList, OUT TStringList &slList)
|
||
|
{
|
||
|
ConvertDelimitedListToStringList(strDelimitedList, (WCHAR) ',', slList);
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ConvertSpaceDelimitedListToStringList
|
||
|
//
|
||
|
// Purpose: Convert a space delimited list to a TStringList
|
||
|
//
|
||
|
// Arguments:
|
||
|
// strDelimitedList [in] Space delimited list
|
||
|
// slList [out] list of string items
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
// Author: kumarp 23-December-97
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
void ConvertSpaceDelimitedListToStringList(IN const tstring& strDelimitedList,
|
||
|
OUT TStringList &slList)
|
||
|
{
|
||
|
ConvertDelimitedListToStringList(strDelimitedList, ' ', slList);
|
||
|
}
|
||
|
|
||
|
void ConvertStringListToCommaList(IN const TStringList &slList, OUT tstring &strList)
|
||
|
{
|
||
|
ConvertStringListToDelimitedList(slList, strList, ',');
|
||
|
}
|
||
|
|
||
|
void ConvertStringListToDelimitedList(IN const TStringList &slList,
|
||
|
OUT tstring &strList, IN WCHAR chDelimiter)
|
||
|
{
|
||
|
TStringListIter pos = slList.begin();
|
||
|
tstring strTemp;
|
||
|
WORD i=0;
|
||
|
static const WCHAR szSpecialChars[] = L" %=";
|
||
|
|
||
|
while (pos != slList.end())
|
||
|
{
|
||
|
strTemp = **pos++;
|
||
|
|
||
|
//
|
||
|
// put quotes around any strings that have chars that setupapi doesn't like.
|
||
|
//
|
||
|
if (strTemp.empty() ||
|
||
|
(L'\"' != *(strTemp.c_str()) &&
|
||
|
wcscspn(strTemp.c_str(), szSpecialChars) < strTemp.size()))
|
||
|
{
|
||
|
strTemp = '"' + strTemp + '"';
|
||
|
}
|
||
|
|
||
|
if (i)
|
||
|
{
|
||
|
strList = strList + chDelimiter + strTemp;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
strList = strTemp;
|
||
|
}
|
||
|
++i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsBoolString
|
||
|
//
|
||
|
// Purpose: Parse a string to decide if it represents a boolean value
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pszStr [in] string
|
||
|
// pbValue [out] pointer to BOOL value parsed
|
||
|
//
|
||
|
// Returns: TRUE on success, FALSE otherwise
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
BOOL IsBoolString(IN PCWSTR pszStr, OUT BOOL *pbValue)
|
||
|
{
|
||
|
if ((!_wcsicmp(pszStr, L"yes")) ||
|
||
|
(!_wcsicmp(pszStr, L"true")) ||
|
||
|
(!_wcsicmp(pszStr, L"1")))
|
||
|
{
|
||
|
*pbValue = TRUE;
|
||
|
return TRUE;
|
||
|
}
|
||
|
else if ((!_wcsicmp(pszStr, L"no")) ||
|
||
|
(!_wcsicmp(pszStr, L"false")) ||
|
||
|
(!_wcsicmp(pszStr, L"0")))
|
||
|
{
|
||
|
*pbValue = FALSE;
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: FIsInStringArray
|
||
|
//
|
||
|
// Purpose: Find out if a string exists in an array
|
||
|
//
|
||
|
// Arguments:
|
||
|
// ppszStrings [in] array of strings
|
||
|
// cNumStrings [in] num strings in array
|
||
|
// pszStringToFind [in] string to find
|
||
|
//
|
||
|
// Returns: TRUE on success, FALSE otherwise
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
BOOL FIsInStringArray(
|
||
|
IN const PCWSTR* ppszStrings,
|
||
|
IN DWORD cNumStrings,
|
||
|
IN PCWSTR pszStringToFind,
|
||
|
OUT UINT* puIndex)
|
||
|
{
|
||
|
for (DWORD isz = 0; isz < cNumStrings; isz++)
|
||
|
{
|
||
|
if (!lstrcmpiW(ppszStrings[isz], pszStringToFind))
|
||
|
{
|
||
|
if (puIndex)
|
||
|
{
|
||
|
*puIndex = isz;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: HrRegOpenServiceKey
|
||
|
//
|
||
|
// Purpose: Open reg key for the given service
|
||
|
//
|
||
|
// Arguments:
|
||
|
// szServiceName [in] name of service
|
||
|
// samDesired [in] SAM required
|
||
|
// phKey [out] pointer to handle of reg key
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwise an error code
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
HRESULT HrRegOpenServiceKey(
|
||
|
IN PCWSTR pszServiceName,
|
||
|
IN REGSAM samDesired,
|
||
|
OUT HKEY* phKey)
|
||
|
{
|
||
|
DefineFunctionName("HrRegOpenServiceKey");
|
||
|
|
||
|
AssertValidReadPtr(pszServiceName);
|
||
|
AssertValidWritePtr(phKey);
|
||
|
|
||
|
*phKey = NULL;
|
||
|
|
||
|
HRESULT hr;
|
||
|
tstring strService;
|
||
|
|
||
|
strService = c_szRegKeyServices;
|
||
|
strService += L"\\";
|
||
|
strService += pszServiceName;
|
||
|
|
||
|
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, strService.c_str(),
|
||
|
samDesired, phKey);
|
||
|
|
||
|
TraceErrorOptional(__FUNCNAME__, hr,
|
||
|
(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr));
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: HrRegOpenServiceSubKey
|
||
|
//
|
||
|
// Purpose: Open sub key of a service key
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pszServiceName [in] name of service
|
||
|
// pszSubKey [in] name of sub key
|
||
|
// samDesired [in] SAM required
|
||
|
// phKey [out] pointer to handle of key opened
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwise an error code
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
HRESULT HrRegOpenServiceSubKey(
|
||
|
IN PCWSTR pszServiceName,
|
||
|
IN PCWSTR pszSubKey,
|
||
|
IN REGSAM samDesired,
|
||
|
OUT HKEY* phKey)
|
||
|
{
|
||
|
AssertValidReadPtr(pszServiceName);
|
||
|
AssertValidReadPtr(pszSubKey);
|
||
|
AssertValidWritePtr(phKey);
|
||
|
|
||
|
DefineFunctionName("HrRegOpenServiceSubKey");
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
tstring strKey;
|
||
|
strKey = pszServiceName;
|
||
|
strKey += L"\\";
|
||
|
strKey += pszSubKey;
|
||
|
|
||
|
hr = HrRegOpenServiceKey(strKey.c_str(), samDesired, phKey);
|
||
|
|
||
|
TraceError(__FUNCNAME__, hr);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: FIsServiceKeyPresent
|
||
|
//
|
||
|
// Purpose: Check if a service reg key is present
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pszServiceName [in] name of service
|
||
|
//
|
||
|
// Returns: TRUE on success, FALSE otherwise
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
BOOL FIsServiceKeyPresent(IN PCWSTR pszServiceName)
|
||
|
{
|
||
|
BOOL fResult = FALSE;
|
||
|
|
||
|
HKEY hkeyService;
|
||
|
HRESULT hr;
|
||
|
|
||
|
hr = HrRegOpenServiceKey(pszServiceName, KEY_READ, &hkeyService);
|
||
|
if (S_OK == hr)
|
||
|
{
|
||
|
// we just wanted to see if service is installed
|
||
|
RegCloseKey(hkeyService);
|
||
|
fResult = TRUE;
|
||
|
}
|
||
|
|
||
|
return fResult;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: EraseAndDeleteAll
|
||
|
//
|
||
|
// Purpose: Erase each element and then delete string array
|
||
|
//
|
||
|
// Arguments:
|
||
|
// sa [in] pointer to array of strings
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
void EraseAndDeleteAll(IN TStringArray* sa)
|
||
|
{
|
||
|
for (size_t i=0; i < sa->size(); i++)
|
||
|
{
|
||
|
delete (*sa)[i];
|
||
|
}
|
||
|
sa->erase(sa->begin(), sa->end());
|
||
|
}
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: AppendToPath
|
||
|
//
|
||
|
// Purpose: Append a subpath/filename to a path
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pstrPath [in] path
|
||
|
// szItem [in] item to append
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
void AppendToPath(IN OUT tstring* pstrPath, IN PCWSTR szItem)
|
||
|
{
|
||
|
if (pstrPath->c_str()[pstrPath->size()-1] != L'\\')
|
||
|
{
|
||
|
*pstrPath += L'\\';
|
||
|
}
|
||
|
|
||
|
*pstrPath += szItem;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ConvertDelimitedListToStringArray
|
||
|
//
|
||
|
// Purpose: Convert a delimited list to an array
|
||
|
//
|
||
|
// Arguments:
|
||
|
// strDelimitedList [in] delimited list (e.g. "a,b,c")
|
||
|
// chDelimiter [in] delimiter char
|
||
|
// saStrings [out] array of strings
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
void ConvertDelimitedListToStringArray(
|
||
|
IN const tstring& strDelimitedList,
|
||
|
IN WCHAR chDelimiter,
|
||
|
OUT TStringArray &saStrings)
|
||
|
{
|
||
|
PCWSTR pszDelimitedList = strDelimitedList.c_str();
|
||
|
DWORD i=0, dwStart;
|
||
|
|
||
|
EraseAndDeleteAll(&saStrings);
|
||
|
|
||
|
tstring strTemp;
|
||
|
DWORD dwNumChars;
|
||
|
while (pszDelimitedList[i])
|
||
|
{
|
||
|
dwStart = i;
|
||
|
while (pszDelimitedList[i] && (pszDelimitedList[i] != chDelimiter))
|
||
|
{
|
||
|
++i;
|
||
|
}
|
||
|
|
||
|
// if each item is enclosed in quotes. strip the quotes
|
||
|
dwNumChars = i - dwStart;
|
||
|
if (pszDelimitedList[dwStart] == L'"')
|
||
|
{
|
||
|
dwStart++;
|
||
|
dwNumChars -= 2;
|
||
|
}
|
||
|
|
||
|
strTemp = strDelimitedList.substr(dwStart, dwNumChars);
|
||
|
saStrings.push_back(new tstring(strTemp));
|
||
|
if (pszDelimitedList[i])
|
||
|
{
|
||
|
++i;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ConvertCommaDelimitedListToStringList
|
||
|
//
|
||
|
// Purpose: Convert a comma delimited list to an array
|
||
|
//
|
||
|
// Arguments:
|
||
|
// strDelimitedList [in] delimited list (e.g. "a,b,c")
|
||
|
// saStrings [out] array of strings
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
// Author: kumarp 12-February-98
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
void ConvertCommaDelimitedListToStringArray(
|
||
|
IN const tstring& strDelimitedList,
|
||
|
OUT TStringArray &saStrings)
|
||
|
{
|
||
|
ConvertDelimitedListToStringArray(strDelimitedList, L',', saStrings);
|
||
|
}
|
||
|
|