windows-nt/Source/XPSP1/NT/shell/ext/cscui/cscentry.cpp
2020-09-26 16:20:57 +08:00

344 lines
8.5 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: cscentry.cpp
//
//--------------------------------------------------------------------------
#include <pch.h>
#pragma hdrstop
#include "cscentry.h"
#include "strings.h"
// Default location in the registry:
// HKLM\Software\Microsoft\Windows\CurrentVersion\NetCache\<logname>
// Entry Key Name
// - <GUID value>
//------------------------------------------------------
int CALLBACK CSCEntry_CompareGuid(LPVOID p1, LPVOID p2, LPARAM lParam)
{
int nResult = -1;
CSCEntry *pEntry1 = reinterpret_cast<CSCEntry*>(p1);
CSCEntry *pEntry2 = reinterpret_cast<CSCEntry*>(p2);
GUID guid1 = GUID_NULL;
GUID guid2 = GUID_NULL;
if (pEntry1)
guid1 = pEntry1->Guid();
else if (lParam)
guid1 = *(const GUID*)lParam;
if (pEntry2)
guid2 = pEntry2->Guid();
if (IsEqualGUID(guid1, guid2))
nResult = 0;
return nResult;
}
//------------------------------------------------------
int CALLBACK CSCEntry_CompareName(LPVOID p1, LPVOID p2, LPARAM lParam)
{
int nResult = 0;
CSCEntry *pEntry1 = reinterpret_cast<CSCEntry*>(p1);
CSCEntry *pEntry2 = reinterpret_cast<CSCEntry*>(p2);
LPCTSTR pszName1 = NULL;
LPCTSTR pszName2 = NULL;
if (pEntry1)
pszName1 = pEntry1->Name();
else if (lParam)
pszName1 = reinterpret_cast<LPCTSTR>(lParam);
if (pEntry2)
pszName2 = pEntry2->Name();
if (pszName1 == NULL)
nResult = -1;
else if (pszName2 == NULL)
nResult = 1;
else
nResult = lstrcmpi(pszName1, pszName2);
return nResult;
}
///////////////////////////////////////////////////////////////////
// CSCEntryLog
//
//
CSCEntryLog::CSCEntryLog(HKEY hkRoot, LPCTSTR pszSubkey)
: m_hdpa(NULL), m_hkRoot(NULL)
{
DWORD dwDisp;
TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::CSCEntryLog");
InitializeCriticalSection(&m_csDPA);
RegCreateKeyEx(hkRoot,
pszSubkey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ENUMERATE_SUB_KEYS | KEY_CREATE_SUB_KEY,
NULL,
&m_hkRoot,
&dwDisp);
m_hdpa = DPA_Create(8);
ReadRegKeys();
TraceLeave();
}
//------------------------------------------------------
int CALLBACK FreeCSCEntry(LPVOID p, LPVOID)
{
CSCEntry *pcsce = reinterpret_cast<CSCEntry*>(p);
delete pcsce;
return 1;
}
CSCEntryLog::~CSCEntryLog()
{
TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::~CSCEntryLog");
DeleteCriticalSection(&m_csDPA);
DPA_DestroyCallback(m_hdpa, FreeCSCEntry, 0);
if (m_hkRoot)
RegCloseKey(m_hkRoot);
TraceLeave();
}
//------------------------------------------------------
CSCEntry* CSCEntryLog::Get(REFGUID rguid)
{
CSCEntry *pcscEntry = NULL;
int iEntry = -1;
TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Get");
EnterCriticalSection(&m_csDPA);
iEntry = DPA_Search(m_hdpa,
NULL,
0,
CSCEntry_CompareGuid,
(LPARAM)&rguid,
0);
if (iEntry != -1)
pcscEntry = (CSCEntry*)DPA_FastGetPtr(m_hdpa, iEntry);
LeaveCriticalSection(&m_csDPA);
TraceLeaveValue(pcscEntry);
}
//------------------------------------------------------
CSCEntry* CSCEntryLog::Get(LPCTSTR pszName)
{
CSCEntry *pcscEntry = NULL;
int iEntry = -1;
if (!pszName || !*pszName)
return NULL;
TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Get");
EnterCriticalSection(&m_csDPA);
iEntry = DPA_Search(m_hdpa,
NULL,
0,
CSCEntry_CompareName,
(LPARAM)pszName,
DPAS_SORTED);
if (iEntry != -1)
pcscEntry = (CSCEntry*)DPA_FastGetPtr(m_hdpa, iEntry);
LeaveCriticalSection(&m_csDPA);
TraceLeaveValue(pcscEntry);
}
//------------------------------------------------------
CSCEntry* CSCEntryLog::Add(LPCTSTR pszName)
{
CSCEntry *pcscEntry;
TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Add");
TraceAssert(pszName);
// Look for an existing entry
pcscEntry = Get(pszName);
if (!pcscEntry)
{
LPTSTR pszTemp = NULL;
// Make a copy of the name string so OpenKeyInternal can
// munge it if necessary.
if (LocalAllocString(&pszTemp, pszName))
{
pcscEntry = CreateFromKey(pszTemp);
if (pcscEntry)
{
EnterCriticalSection(&m_csDPA);
DPA_AppendPtr(m_hdpa, pcscEntry);
DPA_Sort(m_hdpa, CSCEntry_CompareName, 0);
LeaveCriticalSection(&m_csDPA);
}
LocalFreeString(&pszTemp);
}
}
TraceLeaveValue(pcscEntry);
}
//------------------------------------------------------
HKEY CSCEntryLog::OpenKey(LPCTSTR pszSubkey, REGSAM samDesired)
{
HKEY hkEntry = NULL;
LPTSTR pszTemp = NULL;
if (!pszSubkey || !*pszSubkey)
return NULL;
// Make a copy of the name string so OpenKeyInternal can
// munge it if necessary.
if (LocalAllocString(&pszTemp, pszSubkey))
{
hkEntry = OpenKeyInternal(pszTemp, samDesired);
LocalFreeString(&pszTemp);
}
return hkEntry;
}
//------------------------------------------------------
HKEY CSCEntryLog::OpenKeyInternal(LPTSTR pszSubkey, REGSAM samDesired)
{
HKEY hkEntry = NULL;
LPTSTR pszSlash;
DWORD dwDisp;
if (!m_hkRoot)
return NULL;
// Registry keys can't have backslashes in their names.
// Replace backslashes with forward slashes.
pszSlash = pszSubkey;
while (pszSlash = StrChr(pszSlash, TEXT('\\')))
*pszSlash++ = TEXT('/');
RegCreateKeyEx(m_hkRoot,
pszSubkey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
samDesired,
NULL,
&hkEntry,
&dwDisp);
// Restore backslashes
pszSlash = pszSubkey;
while (pszSlash = StrChr(pszSlash, TEXT('/')))
*pszSlash++ = TEXT('\\');
return hkEntry;
}
//------------------------------------------------------
CSCEntry* CSCEntryLog::CreateFromKey(LPTSTR pszSubkey)
{
CSCEntry *pEntry = NULL;
HKEY hkEntry;
hkEntry = OpenKeyInternal(pszSubkey, KEY_QUERY_VALUE | KEY_SET_VALUE);
if (hkEntry)
{
GUID guid = GUID_NULL;
DWORD dwSize = sizeof(guid);
if (ERROR_SUCCESS != RegQueryValueEx(hkEntry,
c_szEntryID,
NULL,
NULL,
(LPBYTE)&guid,
&dwSize))
{
// Doesn't exist, create a new GUID
CoCreateGuid(&guid);
RegSetValueEx(hkEntry,
c_szEntryID,
0,
REG_BINARY,
(LPBYTE)&guid,
sizeof(guid));
}
pEntry = new CSCEntry(pszSubkey, guid);
RegCloseKey(hkEntry);
}
return pEntry;
}
//------------------------------------------------------
HRESULT CSCEntryLog::ReadRegKeys()
{
HRESULT hRes = S_OK;
DWORD dwIndex = 0;
TCHAR szKeyname[MAX_PATH];
DWORD dwcbSize;
TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::ReadRegKeys");
if (!m_hkRoot || !m_hdpa)
TraceLeaveResult(E_UNEXPECTED);
EnterCriticalSection(&m_csDPA);
// Read all existing records from the Registry
for (dwIndex=0; ; dwIndex++)
{
dwcbSize = ARRAYSIZE(szKeyname);
if (ERROR_SUCCESS != RegEnumKeyEx(m_hkRoot,
dwIndex,
szKeyname,
&dwcbSize,
NULL,
NULL,
NULL,
NULL))
{
break;
}
CSCEntry *pcsce = CreateFromKey(szKeyname);
if (pcsce)
DPA_AppendPtr(m_hdpa, pcsce);
}
DPA_Sort(m_hdpa, CSCEntry_CompareName, 0);
LeaveCriticalSection(&m_csDPA);
TraceLeaveResult(hRes);
}