Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: base/services/dnsrslvr/cache.c * PURPOSE: DNS cache functions * PROGRAMMER: Peter Hater */
#include "precomp.h"
#define NDEBUG#include <debug.h>
static RESOLVER_CACHE DnsCache;static BOOL DnsCacheInitialized = FALSE;
#define DnsCacheLock() do { EnterCriticalSection(&DnsCache.Lock); } while (0)#define DnsCacheUnlock() do { LeaveCriticalSection(&DnsCache.Lock); } while (0)
VOIDDnsIntCacheInitialize(VOID){ DPRINT("DnsIntCacheInitialize()\n");
/* Check if we're initialized */ if (DnsCacheInitialized) return;
/* Initialize the cache lock and namespace list */ InitializeCriticalSection((LPCRITICAL_SECTION)&DnsCache.Lock); InitializeListHead(&DnsCache.RecordList); DnsCacheInitialized = TRUE;}
VOIDDnsIntCacheFree(VOID){ DPRINT("DnsIntCacheFree()\n");
/* Check if we're initialized */ if (!DnsCacheInitialized) return;
if (!DnsCache.RecordList.Flink) return;
DnsIntCacheFlush(CACHE_FLUSH_ALL);
DeleteCriticalSection(&DnsCache.Lock); DnsCacheInitialized = FALSE;}
VOIDDnsIntCacheRemoveEntryItem(PRESOLVER_CACHE_ENTRY CacheEntry){ DPRINT("DnsIntCacheRemoveEntryItem(%p)\n", CacheEntry);
/* Remove the entry from the list */ RemoveEntryList(&CacheEntry->CacheLink);
/* Free record */ DnsRecordListFree(CacheEntry->Record, DnsFreeRecordList);
/* Delete us */ HeapFree(GetProcessHeap(), 0, CacheEntry);}
DNS_STATUSDnsIntCacheFlush( _In_ ULONG ulFlags){ PLIST_ENTRY Entry, NextEntry; PRESOLVER_CACHE_ENTRY CacheEntry;
DPRINT("DnsIntCacheFlush(%lu)\n", ulFlags);
/* Lock the cache */ DnsCacheLock();
/* Loop every entry */ Entry = DnsCache.RecordList.Flink; while (Entry != &DnsCache.RecordList) { NextEntry = Entry->Flink;
/* Get this entry */ CacheEntry = CONTAINING_RECORD(Entry, RESOLVER_CACHE_ENTRY, CacheLink);
/* Remove it from list */ if (((ulFlags & CACHE_FLUSH_HOSTS_FILE_ENTRIES) && (CacheEntry->bHostsFileEntry != FALSE)) || ((ulFlags & CACHE_FLUSH_NON_HOSTS_FILE_ENTRIES) && (CacheEntry->bHostsFileEntry == FALSE))) DnsIntCacheRemoveEntryItem(CacheEntry);
/* Move to the next entry */ Entry = NextEntry; }
/* Unlock the cache */ DnsCacheUnlock();
return ERROR_SUCCESS;}
DNS_STATUSDnsIntFlushCacheEntry( _In_ LPCWSTR pszName, _In_ WORD wType){ PLIST_ENTRY Entry, NextEntry; PRESOLVER_CACHE_ENTRY CacheEntry;
DPRINT("DnsIntFlushCacheEntry(%S %x)\n", pszName, wType);
/* Lock the cache */ DnsCacheLock();
/* Loop every entry */ Entry = DnsCache.RecordList.Flink; while (Entry != &DnsCache.RecordList) { NextEntry = Entry->Flink;
/* Get this entry */ CacheEntry = CONTAINING_RECORD(Entry, RESOLVER_CACHE_ENTRY, CacheLink);
/* Remove it from the list */ if ((_wcsicmp(CacheEntry->Record->pName, pszName) == 0) && (CacheEntry->bHostsFileEntry == FALSE)) { if ((wType == DNS_TYPE_ANY) || (CacheEntry->Record->wType == wType)) { DnsIntCacheRemoveEntryItem(CacheEntry); } }
/* Move to the next entry */ Entry = NextEntry; }
/* Unlock the cache */ DnsCacheUnlock();
return ERROR_SUCCESS;}
DNS_STATUSDnsIntCacheGetEntryByName( LPCWSTR Name, WORD wType, DWORD dwFlags, PDNS_RECORDW *Record){ DNS_STATUS Status = DNS_INFO_NO_RECORDS; PRESOLVER_CACHE_ENTRY CacheEntry; PLIST_ENTRY NextEntry;
DPRINT("DnsIntCacheGetEntryByName(%S %hu 0x%lx %p)\n", Name, wType, dwFlags, Record);
/* Assume failure */ *Record = NULL;
/* Lock the cache */ DnsCacheLock();
/* Match the Id with all the entries in the List */ NextEntry = DnsCache.RecordList.Flink; while (NextEntry != &DnsCache.RecordList) { /* Get the Current Entry */ CacheEntry = CONTAINING_RECORD(NextEntry, RESOLVER_CACHE_ENTRY, CacheLink);
/* Check if this is the Catalog Entry ID we want */ if (_wcsicmp(CacheEntry->Record->pName, Name) == 0) { /* Copy the entry and return it */ *Record = DnsRecordSetCopyEx(CacheEntry->Record, DnsCharSetUnicode, DnsCharSetUnicode); Status = ERROR_SUCCESS; break; }
NextEntry = NextEntry->Flink; }
/* Release the cache */ DnsCacheUnlock();
return Status;}
BOOLDnsIntCacheRemoveEntryByName(LPCWSTR Name){ BOOL Ret = FALSE; PRESOLVER_CACHE_ENTRY CacheEntry; PLIST_ENTRY NextEntry;
DPRINT("DnsIntCacheRemoveEntryByName(%S)\n", Name);
/* Lock the cache */ DnsCacheLock();
/* Match the Id with all the entries in the List */ NextEntry = DnsCache.RecordList.Flink; while (NextEntry != &DnsCache.RecordList) { /* Get the Current Entry */ CacheEntry = CONTAINING_RECORD(NextEntry, RESOLVER_CACHE_ENTRY, CacheLink);
/* Check if this is the Catalog Entry ID we want */ if (_wcsicmp(CacheEntry->Record->pName, Name) == 0) { /* Remove the entry */ DnsIntCacheRemoveEntryItem(CacheEntry); Ret = TRUE; break; }
NextEntry = NextEntry->Flink; }
/* Release the cache */ DnsCacheUnlock();
/* Return */ return Ret;}
VOIDDnsIntCacheAddEntry( _In_ PDNS_RECORDW Record, _In_ BOOL bHostsFileEntry){ PRESOLVER_CACHE_ENTRY Entry;
DPRINT("DnsIntCacheAddEntry(%p %u)\n", Record, bHostsFileEntry);
DPRINT("Name: %S\n", Record->pName); DPRINT("TTL: %lu\n", Record->dwTtl);
/* Lock the cache */ DnsCacheLock();
/* Match the Id with all the entries in the List */ Entry = (PRESOLVER_CACHE_ENTRY)HeapAlloc(GetProcessHeap(), 0, sizeof(*Entry)); if (!Entry) return;
Entry->bHostsFileEntry = bHostsFileEntry; Entry->Record = DnsRecordSetCopyEx(Record, DnsCharSetUnicode, DnsCharSetUnicode);
/* Insert it to our List */ InsertTailList(&DnsCache.RecordList, &Entry->CacheLink);
/* Release the cache */ DnsCacheUnlock();}
DNS_STATUSDnsIntCacheGetEntries( _Out_ DNS_CACHE_ENTRY **ppCacheEntries){ PRESOLVER_CACHE_ENTRY CacheEntry; PLIST_ENTRY NextEntry; PDNS_CACHE_ENTRY pLastEntry = NULL, pNewEntry;
/* Lock the cache */ DnsCacheLock();
*ppCacheEntries = NULL;
NextEntry = DnsCache.RecordList.Flink; while (NextEntry != &DnsCache.RecordList) { /* Get the Current Entry */ CacheEntry = CONTAINING_RECORD(NextEntry, RESOLVER_CACHE_ENTRY, CacheLink);
DPRINT("1 %S %lu\n", CacheEntry->Record->pName, CacheEntry->Record->wType); if (CacheEntry->Record->pNext) { DPRINT("2 %S %lu\n", CacheEntry->Record->pNext->pName, CacheEntry->Record->pNext->wType); }
pNewEntry = midl_user_allocate(sizeof(DNS_CACHE_ENTRY)); if (pNewEntry == NULL) { return ERROR_OUTOFMEMORY; }
pNewEntry->pszName = midl_user_allocate((wcslen(CacheEntry->Record->pName) + 1) * sizeof(WCHAR)); if (pNewEntry->pszName == NULL) { return ERROR_OUTOFMEMORY; }
wcscpy(pNewEntry->pszName, CacheEntry->Record->pName); pNewEntry->wType1 = CacheEntry->Record->wType; pNewEntry->wType2 = 0; pNewEntry->wFlags = 0;
if (pLastEntry == NULL) *ppCacheEntries = pNewEntry; else pLastEntry->pNext = pNewEntry; pLastEntry = pNewEntry;
NextEntry = NextEntry->Flink; }
/* Release the cache */ DnsCacheUnlock();
return ERROR_SUCCESS;}