- Build fixes
[reactos.git] / dll / win32 / mswsock / rnr20 / context.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winsock 2 SPI
4 * FILE: lib/mswsock/lib/init.c
5 * PURPOSE: DLL Initialization
6 */
7
8 /* INCLUDES ******************************************************************/
9 #include "msafd.h"
10
11 /* DATA **********************************************************************/
12
13 LIST_ENTRY ListAnchor;
14 BOOLEAN g_fRnrLockInit;
15 CRITICAL_SECTION g_RnrLock;
16
17 #define AcquireRnR2Lock() EnterCriticalSection(&g_RnrLock);
18 #define ReleaseRnR2Lock() LeaveCriticalSection(&g_RnrLock);
19
20 /* FUNCTIONS *****************************************************************/
21
22 PRNR_CONTEXT
23 WSPAPI
24 RnrCtx_Create(IN HANDLE LookupHandle,
25 IN LPWSTR ServiceName)
26 {
27 PRNR_CONTEXT RnrContext;
28 SIZE_T StringSize = 0;
29
30 /* Get the size of the string */
31 if (ServiceName) StringSize = wcslen(ServiceName);
32
33 /* Allocate the Context */
34 RnrContext = Temp_AllocZero(sizeof(RNR_CONTEXT) + (DWORD)StringSize);
35
36 /* Check that we got one */
37 if (RnrContext)
38 {
39 /* Set it up */
40 RnrContext->RefCount = 2;
41 RnrContext->Handle = (LookupHandle ? LookupHandle : (HANDLE)RnrContext);
42 RnrContext->Instance = -1;
43 RnrContext->Signature = 0xaabbccdd;
44 wcscpy(RnrContext->ServiceName, ServiceName);
45
46 /* Insert it into the list */
47 AcquireRnR2Lock();
48 InsertHeadList(&ListAnchor, &RnrContext->ListEntry);
49 ReleaseRnR2Lock();
50 }
51
52 /* Return it */
53 return RnrContext;
54 }
55
56 VOID
57 WSPAPI
58 RnrCtx_Release(PRNR_CONTEXT RnrContext)
59 {
60 /* Acquire the lock */
61 AcquireRnR2Lock();
62
63 /* Decrease reference count and check if it's still in use */
64 if(!(--RnrContext->RefCount))
65 {
66 /* Remove it from the List */
67 RemoveEntryList(&RnrContext->ListEntry);
68
69 /* Release the lock */
70 ReleaseRnR2Lock();
71
72 /* Deallocated any cached Hostent */
73 if(RnrContext->CachedSaBlob) SaBlob_Free(RnrContext->CachedSaBlob);
74
75 /* Deallocate the Blob */
76 if(RnrContext->CachedBlob.pBlobData)
77 {
78 DnsApiFree(RnrContext->CachedBlob.pBlobData);
79 }
80
81 /* Deallocate the actual context itself */
82 DnsApiFree(RnrContext);
83 }
84 else
85 {
86 /* Release the lock */
87 ReleaseRnR2Lock();
88 }
89 }
90
91 PRNR_CONTEXT
92 WSPAPI
93 RnrCtx_Get(HANDLE LookupHandle,
94 DWORD dwControlFlags,
95 PLONG Instance)
96 {
97 PLIST_ENTRY Entry;
98 PRNR_CONTEXT RnRContext = NULL;
99
100 /* Acquire the lock */
101 AcquireRnR2Lock();
102
103 /* Loop the RNR Context List */
104 for(Entry = ListAnchor.Flink; Entry != &ListAnchor; Entry = Entry->Flink)
105 {
106 /* Get the Current RNR Context */
107 RnRContext = CONTAINING_RECORD(Entry, RNR_CONTEXT, ListEntry);
108
109 /* Check if it matches the one we got */
110 if(RnRContext == (PRNR_CONTEXT)LookupHandle) break;
111 }
112
113 /* If we found it, mark it in use */
114 if(RnRContext) RnRContext->RefCount++;
115
116 /* Increase the Instance and return it */
117 *Instance = ++RnRContext->Instance;
118
119 /* If we're flushing the previous one, then bias the Instance by one */
120 if(dwControlFlags & LUP_FLUSHPREVIOUS) *Instance = ++RnRContext->Instance;
121
122 /* Release the lock */
123 ReleaseRnR2Lock();
124
125 /* Return the Context */
126 return RnRContext;
127 }
128
129 VOID
130 WSPAPI
131 RnrCtx_DecInstance(IN PRNR_CONTEXT RnrContext)
132 {
133 /* Acquire the lock */
134 AcquireRnR2Lock();
135
136 /* Decrease instance count */
137 RnrContext->Instance--;
138
139 /* Release the lock */
140 ReleaseRnR2Lock();
141 }
142
143 VOID
144 WSPAPI
145 RnrCtx_ListCleanup(VOID)
146 {
147 PLIST_ENTRY Entry;
148
149 /* Acquire RnR Lock */
150 AcquireRnR2Lock();
151
152 /* Loop the contexts */
153 while ((Entry = ListAnchor.Flink) != &ListAnchor)
154 {
155 /* Release this context */
156 RnrCtx_Release(CONTAINING_RECORD(Entry, RNR_CONTEXT, ListEntry));
157 }
158
159 /* Release lock */
160 ReleaseRnR2Lock();
161 }
162