windows-nt/Source/XPSP1/NT/base/win32/fusion/settings/keys.cpp
2020-09-26 16:20:57 +08:00

283 lines
5.7 KiB
C++

#include "stdinc.h"
int __cdecl
SxspCompareKeys(
const void *pv1,
const void *pv2
)
{
const struct _SXSP_SETTINGS_KEY *pkey1 = reinterpret_cast<PCSXSP_SETTINGS_KEY>(pv1);
const struct _SXSP_SETTINGS_KEY *pkey2 = reinterpret_cast<PCSXSP_SETTINGS_KEY>(pv2);
return ::FusionpCompareStrings(
pkey1->m_pszKeyName,
pkey1->m_cchKeyName,
pkey2->m_pszKeyName,
pkey2->m_cchKeyName,
true);
}
LONG
SxspInternalKeyToExternalKey(
PSXSP_SETTINGS_KEY KeyIn,
REGSAM samGranted,
PSXS_SETTINGS_KEY &KeyOut
)
{
LONG lResult = ERROR_INTERNAL_ERROR;
FN_TRACE_REG(lResult);
PSXS_SETTINGS_KEY KeyTemp = NULL;
KeyOut = NULL;
INTERNAL_ERROR_CHECK(KeyIn != NULL);
IFALLOCFAILED_EXIT(KeyTemp = new SXS_SETTINGS_KEY);
::InterlockedIncrement(&KeyIn->m_cRef);
KeyTemp->m_InternalKey = KeyIn;
KeyTemp->m_SamGranted = samGranted;
KeyOut = KeyTemp;
lResult = ERROR_SUCCESS;
Exit:
return lResult;
}
void
SxspDestroySettingsKey(
PSXSP_SETTINGS_KEY Key
)
{
FN_TRACE();
ULONG i;
ASSERT(Key != NULL);
if (Key == NULL)
return;
ASSERT(Key->m_cRef == 0);
for (i=0; i<Key->m_cValues; i++)
{
PSXSP_SETTINGS_VALUE &ValueRef = Key->m_prgValues[i];
::SxspDestroySettingsValue(ValueRef);
ValueRef = NULL;
}
for (i=0; i<Key->m_cSubKeys; i++)
{
PSXSP_SETTINGS_KEY &KeyRef = Key->m_prgSubKeys[i];
const PSXSP_SETTINGS_KEY SubKey = KeyRef;
::SxspDetachSettingsKey(SubKey);
::SxspReleaseSettingsKey(SubKey);
KeyRef = NULL;
}
FUSION_RAW_DEALLOC(const_cast<PWSTR>(Key->m_pszKeyName));
FUSION_DELETE_SINGLETON(Key);
}
void
SxspDetachSettingsKey(
PSXSP_SETTINGS_KEY Key
)
{
FN_TRACE();
ASSERT(Key != NULL);
if (Key == NULL)
return;
// You shouldn't detach a key more than once...
ASSERT((Key->m_dwFlags & SXSP_SETTINGS_KEY_FLAG_DETACHED) == 0);
if (Key->m_dwFlags & SXSP_SETTINGS_KEY_FLAG_DETACHED)
return;
ULONG i;
// Detaching a key also detaches all its children...
for (i=0; i<Key->m_cSubKeys; i++)
::SxspDetachSettingsKey(Key->m_prgSubKeys[i]);
}
void
SxspAddRefSettingsKey(
PSXSP_SETTINGS_KEY Key
)
{
ASSERT_NTC(Key != NULL);
if (Key != NULL)
{
ASSERT_NTC(Key->m_cRef != 0);
::InterlockedIncrement(&Key->m_cRef);
}
}
void
SxspReleaseSettingsKey(
PSXSP_SETTINGS_KEY Key
)
{
ASSERT_NTC(Key != NULL);
if (Key != NULL)
{
if (::InterlockedDecrement(&Key->m_cRef) == 0)
::SxspDestroySettingsKey(Key);
}
}
LONG
WINAPI
SxsCloseSettingsKey(
PSXS_SETTINGS_KEY Key
)
{
LONG lResult = ERROR_INTERNAL_ERROR;
FN_TRACE_REG(lResult);
PARAMETER_CHECK(Key != NULL);
::SxspReleaseSettingsKey(Key->m_InternalKey);
Key->m_InternalKey = NULL;
FUSION_DELETE_SINGLETON(Key);
lResult = ERROR_SUCCESS;
Exit:
return lResult;
}
LONG
SxspFindSubkey(
DWORD dwFlags,
PSXSP_SETTINGS_KEY pKeyIn,
PCWSTR pszSubKey,
ULONG cchSubKey,
PSXSP_SETTINGS_KEY &rpKeyOut
)
{
LONG lResult = ERROR_INTERNAL_ERROR;
FN_TRACE_REG(lResult);
SXSP_SETTINGS_KEY KeyToFind;
PARAMETER_CHECK(dwFlags == 0);
PARAMETER_CHECK(pKeyIn != NULL);
PARAMETER_CHECK(cchSubKey == 0 || pszSubKey != NULL);
KeyToFind.m_pszKeyName = pszSubKey;
KeyToFind.m_cchKeyName = cchSubKey;
rpKeyOut = reinterpret_cast<PSXSP_SETTINGS_KEY>(bsearch(&KeyToFind, pKeyIn->m_prgSubKeys, pKeyIn->m_cSubKeys, sizeof(SXSP_SETTINGS_KEY), &SxspCompareKeys));
lResult = ERROR_SUCCESS;
Exit:
return lResult;
}
LONG
SxspNavigateKey(
DWORD dwFlags,
PSXSP_SETTINGS_KEY pKeyIn,
PCWSTR pszSubKeyPath,
ULONG cchSubKeyPath,
ULONG &rcchSubKeyPathConsumed,
PSXSP_SETTINGS_KEY &rpKeyOut
)
{
LONG lResult = ERROR_INTERNAL_ERROR;
FN_TRACE_REG(lResult);
// PCWSTR pszThisSegmentStart = pszSubKeyPath;
// PCWSTR pszSeparator = NULL;
ULONG cchSearched = 0;
// PSXSP_SETTINGS_KEY pKeyFound = NULL;
rpKeyOut = NULL;
rcchSubKeyPathConsumed = 0;
INTERNAL_ERROR_CHECK(dwFlags == 0);
INTERNAL_ERROR_CHECK(pKeyIn != NULL);
while (cchSearched < cchSubKeyPath)
{
const WCHAR wch = pszSubKeyPath[cchSearched];
if (wch == NULL)
{
ASSERT(cchSearched == cchSubKeyPath);
if (cchSearched != cchSubKeyPath)
{
lResult = ERROR_INVALID_PARAMETER;
goto Exit;
}
break;
}
else if (wch == L'\\')
{
break;
}
else
{
}
}
lResult = ERROR_SUCCESS;
Exit:
return lResult;
}
LONG
WINAPI
SxsCreateSettingsKeyExW(
PSXS_SETTINGS_KEY lpKey,
LPCWSTR lpSubKey,
DWORD Reserved,
LPWSTR lpClass,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PSXS_SETTINGS_KEY *lplpKeyResult,
LPDWORD lpdwDisposition
)
{
LONG lResult = ERROR_INTERNAL_ERROR;
FN_TRACE_REG(lResult);
ULONG cchSubKey = 0;
ULONG cchClass = 0;
if (lplpKeyResult != NULL)
*lplpKeyResult = NULL;
if (lpdwDisposition != NULL)
*lpdwDisposition = 0; // is there a better "i don't know yet?" value?
PARAMETER_CHECK(lpKey != NULL);
PARAMETER_CHECK(lpSubKey != NULL);
PARAMETER_CHECK(dwOptions == 0);
PARAMETER_CHECK(lpSecurityAttributes == NULL); // or should we just permit them and ignore them?
PARAMETER_CHECK(lplpKeyResult != NULL);
cchSubKey = wcslen(lpSubKey);
if (lpClass != NULL)
cchClass = wcslen(lpClass);
lResult = ERROR_SUCCESS;
Exit:
return lResult;
}