xref: /reactos/base/services/dnsrslvr/cache.c (revision 0f92924a)
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