Leaked source code of windows server 2003
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.

382 lines
10 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. HRESULT CSCEntryLog::Initialize(HKEY hkRoot, LPCTSTR pszSubkey)
  63. {
  64. HRESULT hr = E_FAIL;
  65. DWORD dwErr;
  66. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Initialize");
  67. m_bCSInited = InitializeCriticalSectionAndSpinCount(&m_csDPA, 0);
  68. if (m_bCSInited)
  69. {
  70. DWORD dwDisp;
  71. dwErr = RegCreateKeyEx(hkRoot,
  72. pszSubkey,
  73. 0,
  74. NULL,
  75. REG_OPTION_NON_VOLATILE,
  76. KEY_ENUMERATE_SUB_KEYS | KEY_CREATE_SUB_KEY,
  77. NULL,
  78. &m_hkRoot,
  79. &dwDisp);
  80. if (ERROR_SUCCESS == dwErr)
  81. {
  82. m_hdpa = DPA_Create(8);
  83. if (m_hdpa)
  84. {
  85. hr = ReadRegKeys();
  86. }
  87. else
  88. {
  89. hr = E_OUTOFMEMORY;
  90. }
  91. }
  92. else
  93. {
  94. hr = HRESULT_FROM_WIN32(dwErr);
  95. }
  96. }
  97. else
  98. {
  99. hr = ResultFromLastError();
  100. }
  101. TraceLeaveResult(hr);
  102. }
  103. //------------------------------------------------------
  104. int CALLBACK FreeCSCEntry(LPVOID p, LPVOID)
  105. {
  106. CSCEntry *pcsce = reinterpret_cast<CSCEntry*>(p);
  107. delete pcsce;
  108. return 1;
  109. }
  110. CSCEntryLog::~CSCEntryLog()
  111. {
  112. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::~CSCEntryLog");
  113. if (m_bCSInited)
  114. {
  115. DeleteCriticalSection(&m_csDPA);
  116. }
  117. DPA_DestroyCallback(m_hdpa, FreeCSCEntry, 0);
  118. if (m_hkRoot)
  119. RegCloseKey(m_hkRoot);
  120. TraceLeave();
  121. }
  122. //------------------------------------------------------
  123. CSCEntry* CSCEntryLog::Get(REFGUID rguid)
  124. {
  125. CSCEntry *pcscEntry = NULL;
  126. int iEntry = -1;
  127. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Get");
  128. EnterCriticalSection(&m_csDPA);
  129. iEntry = DPA_Search(m_hdpa,
  130. NULL,
  131. 0,
  132. CSCEntry_CompareGuid,
  133. (LPARAM)&rguid,
  134. 0);
  135. if (iEntry != -1)
  136. pcscEntry = (CSCEntry*)DPA_FastGetPtr(m_hdpa, iEntry);
  137. LeaveCriticalSection(&m_csDPA);
  138. TraceLeaveValue(pcscEntry);
  139. }
  140. //------------------------------------------------------
  141. CSCEntry* CSCEntryLog::Get(LPCTSTR pszName)
  142. {
  143. CSCEntry *pcscEntry = NULL;
  144. int iEntry = -1;
  145. if (!pszName || !*pszName)
  146. return NULL;
  147. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Get");
  148. EnterCriticalSection(&m_csDPA);
  149. iEntry = DPA_Search(m_hdpa,
  150. NULL,
  151. 0,
  152. CSCEntry_CompareName,
  153. (LPARAM)pszName,
  154. DPAS_SORTED);
  155. if (iEntry != -1)
  156. pcscEntry = (CSCEntry*)DPA_FastGetPtr(m_hdpa, iEntry);
  157. LeaveCriticalSection(&m_csDPA);
  158. TraceLeaveValue(pcscEntry);
  159. }
  160. //------------------------------------------------------
  161. CSCEntry* CSCEntryLog::Add(LPCTSTR pszName)
  162. {
  163. CSCEntry *pcscEntry;
  164. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::Add");
  165. TraceAssert(pszName);
  166. // Look for an existing entry
  167. pcscEntry = Get(pszName);
  168. if (!pcscEntry)
  169. {
  170. LPTSTR pszTemp = NULL;
  171. // Make a copy of the name string so OpenKeyInternal can
  172. // munge it if necessary.
  173. if (LocalAllocString(&pszTemp, pszName))
  174. {
  175. pcscEntry = CreateFromKey(pszTemp);
  176. if (pcscEntry)
  177. {
  178. EnterCriticalSection(&m_csDPA);
  179. DPA_AppendPtr(m_hdpa, pcscEntry);
  180. DPA_Sort(m_hdpa, CSCEntry_CompareName, 0);
  181. LeaveCriticalSection(&m_csDPA);
  182. }
  183. LocalFreeString(&pszTemp);
  184. }
  185. }
  186. TraceLeaveValue(pcscEntry);
  187. }
  188. //------------------------------------------------------
  189. HKEY CSCEntryLog::OpenKey(LPCTSTR pszSubkey, REGSAM samDesired)
  190. {
  191. HKEY hkEntry = NULL;
  192. LPTSTR pszTemp = NULL;
  193. if (!pszSubkey || !*pszSubkey)
  194. return NULL;
  195. // Make a copy of the name string so OpenKeyInternal can
  196. // munge it if necessary.
  197. if (LocalAllocString(&pszTemp, pszSubkey))
  198. {
  199. hkEntry = OpenKeyInternal(pszTemp, samDesired);
  200. LocalFreeString(&pszTemp);
  201. }
  202. return hkEntry;
  203. }
  204. //------------------------------------------------------
  205. HKEY CSCEntryLog::OpenKeyInternal(LPTSTR pszSubkey, REGSAM samDesired)
  206. {
  207. HKEY hkEntry = NULL;
  208. LPTSTR pszSlash;
  209. DWORD dwDisp;
  210. if (!m_hkRoot)
  211. return NULL;
  212. // Registry keys can't have backslashes in their names.
  213. // Replace backslashes with forward slashes.
  214. pszSlash = pszSubkey;
  215. while (pszSlash = StrChr(pszSlash, TEXT('\\')))
  216. *pszSlash++ = TEXT('/');
  217. RegCreateKeyEx(m_hkRoot,
  218. pszSubkey,
  219. 0,
  220. NULL,
  221. REG_OPTION_NON_VOLATILE,
  222. samDesired,
  223. NULL,
  224. &hkEntry,
  225. &dwDisp);
  226. // Restore backslashes
  227. pszSlash = pszSubkey;
  228. while (pszSlash = StrChr(pszSlash, TEXT('/')))
  229. *pszSlash++ = TEXT('\\');
  230. return hkEntry;
  231. }
  232. //------------------------------------------------------
  233. CSCEntry* CSCEntryLog::CreateFromKey(LPTSTR pszSubkey)
  234. {
  235. CSCEntry *pEntry = NULL;
  236. HKEY hkEntry;
  237. hkEntry = OpenKeyInternal(pszSubkey, KEY_QUERY_VALUE | KEY_SET_VALUE);
  238. if (hkEntry)
  239. {
  240. HRESULT hr = S_OK;
  241. GUID guid = GUID_NULL;
  242. DWORD dwSize = sizeof(guid);
  243. DWORD dwType;
  244. if (ERROR_SUCCESS != RegQueryValueEx(hkEntry,
  245. c_szEntryID,
  246. NULL,
  247. &dwType,
  248. (LPBYTE)&guid,
  249. &dwSize)
  250. || dwType != REG_BINARY || dwSize != sizeof(guid))
  251. {
  252. // Doesn't exist, create a new GUID
  253. hr = CoCreateGuid(&guid);
  254. if (SUCCEEDED(hr))
  255. {
  256. DWORD dwErr = RegSetValueEx(hkEntry,
  257. c_szEntryID,
  258. 0,
  259. REG_BINARY,
  260. (LPBYTE)&guid,
  261. sizeof(guid));
  262. hr = HRESULT_FROM_WIN32(dwErr);
  263. }
  264. }
  265. if (SUCCEEDED(hr))
  266. {
  267. pEntry = new CSCEntry(guid);
  268. if (pEntry && !pEntry->Initialize(pszSubkey))
  269. {
  270. delete pEntry;
  271. pEntry = NULL;
  272. // Leave the registry entry for next time
  273. }
  274. }
  275. RegCloseKey(hkEntry);
  276. }
  277. return pEntry;
  278. }
  279. //------------------------------------------------------
  280. HRESULT CSCEntryLog::ReadRegKeys()
  281. {
  282. HRESULT hRes = S_OK;
  283. DWORD dwIndex = 0;
  284. TCHAR szKeyname[MAX_PATH];
  285. DWORD dwcbSize;
  286. TraceEnter(TRACE_CSCENTRY, "CSCEntryLog::ReadRegKeys");
  287. if (!m_hkRoot || !m_hdpa)
  288. TraceLeaveResult(E_UNEXPECTED);
  289. EnterCriticalSection(&m_csDPA);
  290. // Read all existing records from the Registry
  291. for (dwIndex=0; ; dwIndex++)
  292. {
  293. dwcbSize = ARRAYSIZE(szKeyname);
  294. if (ERROR_SUCCESS != RegEnumKeyEx(m_hkRoot,
  295. dwIndex,
  296. szKeyname,
  297. &dwcbSize,
  298. NULL,
  299. NULL,
  300. NULL,
  301. NULL))
  302. {
  303. break;
  304. }
  305. CSCEntry *pcsce = CreateFromKey(szKeyname);
  306. if (pcsce)
  307. DPA_AppendPtr(m_hdpa, pcsce);
  308. }
  309. DPA_Sort(m_hdpa, CSCEntry_CompareName, 0);
  310. LeaveCriticalSection(&m_csDPA);
  311. TraceLeaveResult(hRes);
  312. }