Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

343 lines
8.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: cscentry.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <pch.h>
  11. #pragma hdrstop
  12. #include "cscentry.h"
  13. #include "strings.h"
  14. // Default location in the registry:
  15. // HKLM\Software\Microsoft\Windows\CurrentVersion\NetCache\<logname>
  16. // Entry Key Name
  17. // - <GUID value>
  18. //------------------------------------------------------
  19. int CALLBACK CSCEntry_CompareGuid(LPVOID p1, LPVOID p2, LPARAM lParam)
  20. {
  21. int nResult = -1;
  22. CSCEntry *pEntry1 = reinterpret_cast<CSCEntry*>(p1);
  23. CSCEntry *pEntry2 = reinterpret_cast<CSCEntry*>(p2);
  24. GUID guid1 = GUID_NULL;
  25. GUID guid2 = GUID_NULL;
  26. if (pEntry1)
  27. guid1 = pEntry1->Guid();
  28. else if (lParam)
  29. guid1 = *(const GUID*)lParam;
  30. if (pEntry2)
  31. guid2 = pEntry2->Guid();
  32. if (IsEqualGUID(guid1, guid2))
  33. nResult = 0;
  34. return nResult;
  35. }
  36. //------------------------------------------------------
  37. int CALLBACK CSCEntry_CompareName(LPVOID p1, LPVOID p2, LPARAM lParam)
  38. {
  39. int nResult = 0;
  40. CSCEntry *pEntry1 = reinterpret_cast<CSCEntry*>(p1);
  41. CSCEntry *pEntry2 = reinterpret_cast<CSCEntry*>(p2);
  42. LPCTSTR pszName1 = NULL;
  43. LPCTSTR pszName2 = NULL;
  44. if (pEntry1)
  45. pszName1 = pEntry1->Name();
  46. else if (lParam)
  47. pszName1 = reinterpret_cast<LPCTSTR>(lParam);
  48. if (pEntry2)
  49. pszName2 = pEntry2->Name();
  50. if (pszName1 == NULL)
  51. nResult = -1;
  52. else if (pszName2 == NULL)
  53. nResult = 1;
  54. else
  55. nResult = lstrcmpi(pszName1, pszName2);
  56. return nResult;
  57. }
  58. ///////////////////////////////////////////////////////////////////
  59. // CSCEntryLog
  60. //
  61. //
  62. CSCEntryLog::CSCEntryLog(HKEY hkRoot, LPCTSTR pszSubkey)
  63. : m_hdpa(NULL), m_hkRoot(NULL)
  64. {
  65. DWORD dwDisp;
  66. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::CSCEntryLog");
  67. InitializeCriticalSection(&m_csDPA);
  68. RegCreateKeyEx(hkRoot,
  69. pszSubkey,
  70. 0,
  71. NULL,
  72. REG_OPTION_NON_VOLATILE,
  73. KEY_ENUMERATE_SUB_KEYS | KEY_CREATE_SUB_KEY,
  74. NULL,
  75. &m_hkRoot,
  76. &dwDisp);
  77. m_hdpa = DPA_Create(8);
  78. ReadRegKeys();
  79. TraceLeave();
  80. }
  81. //------------------------------------------------------
  82. int CALLBACK FreeCSCEntry(LPVOID p, LPVOID)
  83. {
  84. CSCEntry *pcsce = reinterpret_cast<CSCEntry*>(p);
  85. delete pcsce;
  86. return 1;
  87. }
  88. CSCEntryLog::~CSCEntryLog()
  89. {
  90. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::~CSCEntryLog");
  91. DeleteCriticalSection(&m_csDPA);
  92. DPA_DestroyCallback(m_hdpa, FreeCSCEntry, 0);
  93. if (m_hkRoot)
  94. RegCloseKey(m_hkRoot);
  95. TraceLeave();
  96. }
  97. //------------------------------------------------------
  98. CSCEntry* CSCEntryLog::Get(REFGUID rguid)
  99. {
  100. CSCEntry *pcscEntry = NULL;
  101. int iEntry = -1;
  102. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Get");
  103. EnterCriticalSection(&m_csDPA);
  104. iEntry = DPA_Search(m_hdpa,
  105. NULL,
  106. 0,
  107. CSCEntry_CompareGuid,
  108. (LPARAM)&rguid,
  109. 0);
  110. if (iEntry != -1)
  111. pcscEntry = (CSCEntry*)DPA_FastGetPtr(m_hdpa, iEntry);
  112. LeaveCriticalSection(&m_csDPA);
  113. TraceLeaveValue(pcscEntry);
  114. }
  115. //------------------------------------------------------
  116. CSCEntry* CSCEntryLog::Get(LPCTSTR pszName)
  117. {
  118. CSCEntry *pcscEntry = NULL;
  119. int iEntry = -1;
  120. if (!pszName || !*pszName)
  121. return NULL;
  122. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Get");
  123. EnterCriticalSection(&m_csDPA);
  124. iEntry = DPA_Search(m_hdpa,
  125. NULL,
  126. 0,
  127. CSCEntry_CompareName,
  128. (LPARAM)pszName,
  129. DPAS_SORTED);
  130. if (iEntry != -1)
  131. pcscEntry = (CSCEntry*)DPA_FastGetPtr(m_hdpa, iEntry);
  132. LeaveCriticalSection(&m_csDPA);
  133. TraceLeaveValue(pcscEntry);
  134. }
  135. //------------------------------------------------------
  136. CSCEntry* CSCEntryLog::Add(LPCTSTR pszName)
  137. {
  138. CSCEntry *pcscEntry;
  139. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Add");
  140. TraceAssert(pszName);
  141. // Look for an existing entry
  142. pcscEntry = Get(pszName);
  143. if (!pcscEntry)
  144. {
  145. LPTSTR pszTemp = NULL;
  146. // Make a copy of the name string so OpenKeyInternal can
  147. // munge it if necessary.
  148. if (LocalAllocString(&pszTemp, pszName))
  149. {
  150. pcscEntry = CreateFromKey(pszTemp);
  151. if (pcscEntry)
  152. {
  153. EnterCriticalSection(&m_csDPA);
  154. DPA_AppendPtr(m_hdpa, pcscEntry);
  155. DPA_Sort(m_hdpa, CSCEntry_CompareName, 0);
  156. LeaveCriticalSection(&m_csDPA);
  157. }
  158. LocalFreeString(&pszTemp);
  159. }
  160. }
  161. TraceLeaveValue(pcscEntry);
  162. }
  163. //------------------------------------------------------
  164. HKEY CSCEntryLog::OpenKey(LPCTSTR pszSubkey, REGSAM samDesired)
  165. {
  166. HKEY hkEntry = NULL;
  167. LPTSTR pszTemp = NULL;
  168. if (!pszSubkey || !*pszSubkey)
  169. return NULL;
  170. // Make a copy of the name string so OpenKeyInternal can
  171. // munge it if necessary.
  172. if (LocalAllocString(&pszTemp, pszSubkey))
  173. {
  174. hkEntry = OpenKeyInternal(pszTemp, samDesired);
  175. LocalFreeString(&pszTemp);
  176. }
  177. return hkEntry;
  178. }
  179. //------------------------------------------------------
  180. HKEY CSCEntryLog::OpenKeyInternal(LPTSTR pszSubkey, REGSAM samDesired)
  181. {
  182. HKEY hkEntry = NULL;
  183. LPTSTR pszSlash;
  184. DWORD dwDisp;
  185. if (!m_hkRoot)
  186. return NULL;
  187. // Registry keys can't have backslashes in their names.
  188. // Replace backslashes with forward slashes.
  189. pszSlash = pszSubkey;
  190. while (pszSlash = StrChr(pszSlash, TEXT('\\')))
  191. *pszSlash++ = TEXT('/');
  192. RegCreateKeyEx(m_hkRoot,
  193. pszSubkey,
  194. 0,
  195. NULL,
  196. REG_OPTION_NON_VOLATILE,
  197. samDesired,
  198. NULL,
  199. &hkEntry,
  200. &dwDisp);
  201. // Restore backslashes
  202. pszSlash = pszSubkey;
  203. while (pszSlash = StrChr(pszSlash, TEXT('/')))
  204. *pszSlash++ = TEXT('\\');
  205. return hkEntry;
  206. }
  207. //------------------------------------------------------
  208. CSCEntry* CSCEntryLog::CreateFromKey(LPTSTR pszSubkey)
  209. {
  210. CSCEntry *pEntry = NULL;
  211. HKEY hkEntry;
  212. hkEntry = OpenKeyInternal(pszSubkey, KEY_QUERY_VALUE | KEY_SET_VALUE);
  213. if (hkEntry)
  214. {
  215. GUID guid = GUID_NULL;
  216. DWORD dwSize = sizeof(guid);
  217. if (ERROR_SUCCESS != RegQueryValueEx(hkEntry,
  218. c_szEntryID,
  219. NULL,
  220. NULL,
  221. (LPBYTE)&guid,
  222. &dwSize))
  223. {
  224. // Doesn't exist, create a new GUID
  225. CoCreateGuid(&guid);
  226. RegSetValueEx(hkEntry,
  227. c_szEntryID,
  228. 0,
  229. REG_BINARY,
  230. (LPBYTE)&guid,
  231. sizeof(guid));
  232. }
  233. pEntry = new CSCEntry(pszSubkey, guid);
  234. RegCloseKey(hkEntry);
  235. }
  236. return pEntry;
  237. }
  238. //------------------------------------------------------
  239. HRESULT CSCEntryLog::ReadRegKeys()
  240. {
  241. HRESULT hRes = S_OK;
  242. DWORD dwIndex = 0;
  243. TCHAR szKeyname[MAX_PATH];
  244. DWORD dwcbSize;
  245. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::ReadRegKeys");
  246. if (!m_hkRoot || !m_hdpa)
  247. TraceLeaveResult(E_UNEXPECTED);
  248. EnterCriticalSection(&m_csDPA);
  249. // Read all existing records from the Registry
  250. for (dwIndex=0; ; dwIndex++)
  251. {
  252. dwcbSize = ARRAYSIZE(szKeyname);
  253. if (ERROR_SUCCESS != RegEnumKeyEx(m_hkRoot,
  254. dwIndex,
  255. szKeyname,
  256. &dwcbSize,
  257. NULL,
  258. NULL,
  259. NULL,
  260. NULL))
  261. {
  262. break;
  263. }
  264. CSCEntry *pcsce = CreateFromKey(szKeyname);
  265. if (pcsce)
  266. DPA_AppendPtr(m_hdpa, pcsce);
  267. }
  268. DPA_Sort(m_hdpa, CSCEntry_CompareName, 0);
  269. LeaveCriticalSection(&m_csDPA);
  270. TraceLeaveResult(hRes);
  271. }