1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: base/services/dnsrslvr/cache.c 5 * PURPOSE: DNS cache functions 6 * PROGRAMMER: Peter Hater 7 */ 8 9 #include "precomp.h" 10 11 //#define NDEBUG 12 #include <debug.h> 13 14 static RESOLVER_CACHE DnsCache; 15 static BOOL DnsCacheInitialized = FALSE; 16 17 #define DnsCacheLock() do { EnterCriticalSection(&DnsCache.Lock); } while (0) 18 #define DnsCacheUnlock() do { LeaveCriticalSection(&DnsCache.Lock); } while (0) 19 20 VOID 21 DnsIntCacheInitialize(VOID) 22 { 23 DPRINT("DnsIntCacheInitialize\n"); 24 25 /* Check if we're initialized */ 26 if (DnsCacheInitialized) 27 return; 28 29 /* Initialize the cache lock and namespace list */ 30 InitializeCriticalSection((LPCRITICAL_SECTION)&DnsCache.Lock); 31 InitializeListHead(&DnsCache.RecordList); 32 DnsCacheInitialized = TRUE; 33 } 34 35 VOID 36 DnsIntCacheFree(VOID) 37 { 38 DPRINT("DnsIntCacheFree\n"); 39 40 /* Check if we're initialized */ 41 if (!DnsCacheInitialized) 42 return; 43 44 if (!DnsCache.RecordList.Flink) 45 return; 46 47 DnsIntCacheFlush(); 48 49 DeleteCriticalSection(&DnsCache.Lock); 50 DnsCacheInitialized = FALSE; 51 } 52 53 VOID 54 DnsIntCacheRemoveEntryItem(PRESOLVER_CACHE_ENTRY CacheEntry) 55 { 56 DPRINT("DnsIntCacheRemoveEntryItem %p\n", CacheEntry); 57 58 /* Remove the entry from the list */ 59 RemoveEntryList(&CacheEntry->CacheLink); 60 61 /* Free record */ 62 DnsRecordListFree(CacheEntry->Record, DnsFreeRecordList); 63 64 /* Delete us */ 65 HeapFree(GetProcessHeap(), 0, CacheEntry); 66 } 67 68 VOID 69 DnsIntCacheFlush(VOID) 70 { 71 PLIST_ENTRY Entry; 72 PRESOLVER_CACHE_ENTRY CacheEntry; 73 74 DPRINT("DnsIntCacheFlush\n"); 75 76 /* Lock the cache */ 77 DnsCacheLock(); 78 79 /* Loop every entry */ 80 Entry = DnsCache.RecordList.Flink; 81 while (Entry != &DnsCache.RecordList) 82 { 83 /* Get this entry */ 84 CacheEntry = CONTAINING_RECORD(Entry, RESOLVER_CACHE_ENTRY, CacheLink); 85 86 /* Remove it from list */ 87 DnsIntCacheRemoveEntryItem(CacheEntry); 88 89 /* Move to the next entry */ 90 Entry = DnsCache.RecordList.Flink; 91 } 92 93 /* Unlock the cache */ 94 DnsCacheUnlock(); 95 } 96 97 BOOL 98 DnsIntCacheGetEntryFromName(LPCWSTR Name, 99 PDNS_RECORDW *Record) 100 { 101 BOOL Ret = FALSE; 102 PRESOLVER_CACHE_ENTRY CacheEntry; 103 PLIST_ENTRY NextEntry; 104 105 DPRINT("DnsIntCacheGetEntryFromName %ws %p\n", Name, Record); 106 107 /* Assume failure */ 108 *Record = NULL; 109 110 /* Lock the cache */ 111 DnsCacheLock(); 112 113 /* Match the Id with all the entries in the List */ 114 NextEntry = DnsCache.RecordList.Flink; 115 while (NextEntry != &DnsCache.RecordList) 116 { 117 /* Get the Current Entry */ 118 CacheEntry = CONTAINING_RECORD(NextEntry, RESOLVER_CACHE_ENTRY, CacheLink); 119 120 /* Check if this is the Catalog Entry ID we want */ 121 if (_wcsicmp(CacheEntry->Record->pName, Name) == 0) 122 { 123 /* Copy the entry and return it */ 124 *Record = DnsRecordSetCopyEx(CacheEntry->Record, DnsCharSetUnicode, DnsCharSetUnicode); 125 Ret = TRUE; 126 break; 127 } 128 129 NextEntry = NextEntry->Flink; 130 } 131 132 /* Release the cache */ 133 DnsCacheUnlock(); 134 135 /* Return */ 136 return Ret; 137 } 138 139 BOOL 140 DnsIntCacheRemoveEntryByName(LPCWSTR Name) 141 { 142 BOOL Ret = FALSE; 143 PRESOLVER_CACHE_ENTRY CacheEntry; 144 PLIST_ENTRY NextEntry; 145 146 DPRINT("DnsIntCacheRemoveEntryByName %ws\n", Name); 147 148 /* Lock the cache */ 149 DnsCacheLock(); 150 151 /* Match the Id with all the entries in the List */ 152 NextEntry = DnsCache.RecordList.Flink; 153 while (NextEntry != &DnsCache.RecordList) 154 { 155 /* Get the Current Entry */ 156 CacheEntry = CONTAINING_RECORD(NextEntry, RESOLVER_CACHE_ENTRY, CacheLink); 157 158 /* Check if this is the Catalog Entry ID we want */ 159 if (_wcsicmp(CacheEntry->Record->pName, Name) == 0) 160 { 161 /* Remove the entry */ 162 DnsIntCacheRemoveEntryItem(CacheEntry); 163 Ret = TRUE; 164 break; 165 } 166 167 NextEntry = NextEntry->Flink; 168 } 169 170 /* Release the cache */ 171 DnsCacheUnlock(); 172 173 /* Return */ 174 return Ret; 175 } 176 177 VOID 178 DnsIntCacheAddEntry(PDNS_RECORDW Record) 179 { 180 PRESOLVER_CACHE_ENTRY Entry; 181 182 DPRINT("DnsIntCacheRemoveEntryByName %p\n", Record); 183 184 /* Lock the cache */ 185 DnsCacheLock(); 186 187 /* Match the Id with all the entries in the List */ 188 Entry = (PRESOLVER_CACHE_ENTRY)HeapAlloc(GetProcessHeap(), 0, sizeof(*Entry)); 189 if (!Entry) 190 return; 191 192 Entry->Record = DnsRecordSetCopyEx(Record, DnsCharSetUnicode, DnsCharSetUnicode); 193 194 /* Insert it to our List */ 195 InsertTailList(&DnsCache.RecordList, &Entry->CacheLink); 196 197 /* Release the cache */ 198 DnsCacheUnlock(); 199 } 200