//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: cscentry.cpp // //-------------------------------------------------------------------------- #include #pragma hdrstop #include "cscentry.h" #include "strings.h" // Default location in the registry: // HKLM\Software\Microsoft\Windows\CurrentVersion\NetCache\ // Entry Key Name // - //------------------------------------------------------ int CALLBACK CSCEntry_CompareGuid(LPVOID p1, LPVOID p2, LPARAM lParam) { int nResult = -1; CSCEntry *pEntry1 = reinterpret_cast(p1); CSCEntry *pEntry2 = reinterpret_cast(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(p1); CSCEntry *pEntry2 = reinterpret_cast(p2); LPCTSTR pszName1 = NULL; LPCTSTR pszName2 = NULL; if (pEntry1) pszName1 = pEntry1->Name(); else if (lParam) pszName1 = reinterpret_cast(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(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); }