Sync to trunk r65566.
[reactos.git] / dll / win32 / ws2_32 / misc / handle.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 DLL
4 * FILE: misc/handle.c
5 * PURPOSE: Provider handle management
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/09-2000 Created
9 */
10
11 #include "ws2_32.h"
12
13 PPROVIDER_HANDLE_BLOCK ProviderHandleTable;
14 CRITICAL_SECTION ProviderHandleTableLock;
15
16 PPROVIDER_HANDLE
17 GetProviderByHandle(PPROVIDER_HANDLE_BLOCK HandleTable,
18 HANDLE Handle)
19 /*
20 * FUNCTION: Get the data structure for a handle
21 * ARGUMENTS:
22 * HandleTable = Pointer to handle table
23 * Handle = Handle to get data structure for
24 * RETURNS:
25 * Pointer to the data structure identified by the handle on success,
26 * NULL on failure
27 */
28 {
29 PPROVIDER_HANDLE_BLOCK Current;
30 PLIST_ENTRY CurrentEntry;
31 ULONG i;
32
33 WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
34
35 CurrentEntry = HandleTable->Entry.Flink;
36
37 while (CurrentEntry != &HandleTable->Entry)
38 {
39 Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
40
41 for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
42 {
43 if ((Current->Handles[i].Provider != NULL) &&
44 (Current->Handles[i].Handle == Handle))
45 {
46 return &Current->Handles[i];
47 }
48 }
49 CurrentEntry = CurrentEntry->Flink;
50 }
51
52 return NULL;
53 }
54
55
56 VOID
57 CloseAllHandles(PPROVIDER_HANDLE_BLOCK HandleTable)
58 {
59 PPROVIDER_HANDLE_BLOCK Current;
60 PLIST_ENTRY CurrentEntry;
61 PCATALOG_ENTRY Provider;
62 ULONG i;
63
64 WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X).\n", HandleTable));
65
66 CurrentEntry = HandleTable->Entry.Flink;
67
68 while (CurrentEntry != &HandleTable->Entry)
69 {
70 Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
71
72 for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
73 {
74 Provider = Current->Handles[i].Provider;
75 if (Provider != NULL)
76 {
77 DereferenceProviderByPointer(Provider);
78 Current->Handles[i].Handle = (HANDLE)0;
79 Current->Handles[i].Provider = NULL;
80 }
81 }
82 CurrentEntry = CurrentEntry->Flink;
83 }
84 }
85
86
87 VOID
88 DeleteHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable)
89 {
90 PPROVIDER_HANDLE_BLOCK Current;
91 PLIST_ENTRY CurrentEntry;
92
93 CloseAllHandles(HandleTable);
94
95 CurrentEntry = RemoveHeadList(&HandleTable->Entry);
96
97 while (CurrentEntry != &HandleTable->Entry)
98 {
99 Current = CONTAINING_RECORD(CurrentEntry,
100 PROVIDER_HANDLE_BLOCK,
101 Entry);
102
103 HeapFree(GlobalHeap, 0, Current);
104
105 CurrentEntry = RemoveHeadList(&HandleTable->Entry);
106 }
107 }
108
109
110 PCATALOG_ENTRY
111 DeleteProviderHandle(PPROVIDER_HANDLE_BLOCK HandleTable,
112 HANDLE Handle)
113 {
114 PPROVIDER_HANDLE Entry;
115 PCATALOG_ENTRY Provider;
116
117 WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
118
119 Entry = GetProviderByHandle(HandleTable, Handle);
120 if (!Entry)
121 return NULL;
122
123 Provider = Entry->Provider;
124 Entry->Handle = (HANDLE)0;
125 Entry->Provider = NULL;
126
127 return Provider;
128 }
129
130
131 HANDLE
132 CreateProviderHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable,
133 HANDLE Handle,
134 PCATALOG_ENTRY Provider)
135 {
136 PPROVIDER_HANDLE_BLOCK NewBlock;
137 PLIST_ENTRY CurrentEntry;
138 ULONG i;
139
140 WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X) Provider (0x%X).\n",
141 HandleTable, Handle, Provider));
142
143 /* Scan through the currently allocated handle blocks looking for a free slot */
144 CurrentEntry = HandleTable->Entry.Flink;
145 while (CurrentEntry != &HandleTable->Entry)
146 {
147 PPROVIDER_HANDLE_BLOCK Block = CONTAINING_RECORD(CurrentEntry,
148 PROVIDER_HANDLE_BLOCK,
149 Entry);
150
151 for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
152 {
153 WS_DbgPrint(MAX_TRACE, ("Considering slot %ld containing 0x%X.\n",
154 i,
155 Block->Handles[i].Provider));
156 if (Block->Handles[i].Provider == NULL)
157 {
158 Block->Handles[i].Handle = Handle;
159 Block->Handles[i].Provider = Provider;
160 return Handle;
161 }
162 }
163 CurrentEntry = CurrentEntry->Flink;
164 }
165
166 /* Add a new handle block to the end of the list */
167 NewBlock = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(GlobalHeap,
168 0,
169 sizeof(PROVIDER_HANDLE_BLOCK));
170
171 WS_DbgPrint(MID_TRACE,("using table entry %x\n", NewBlock));
172
173 if (!NewBlock)
174 return (HANDLE)0;
175
176 ZeroMemory(NewBlock, sizeof(PROVIDER_HANDLE_BLOCK));
177 InsertTailList(&HandleTable->Entry,
178 &NewBlock->Entry);
179
180 NewBlock->Handles[0].Handle = Handle;
181 NewBlock->Handles[0].Provider = Provider;
182
183 return Handle;
184 }
185
186
187 HANDLE
188 CreateProviderHandle(HANDLE Handle,
189 PCATALOG_ENTRY Provider)
190 {
191 HANDLE h;
192
193 EnterCriticalSection(&ProviderHandleTableLock);
194
195 h = CreateProviderHandleTable(ProviderHandleTable,
196 Handle,
197 Provider);
198
199 LeaveCriticalSection(&ProviderHandleTableLock);
200
201 if (h != NULL)
202 ReferenceProviderByPointer(Provider);
203
204 return h;
205 }
206
207
208 BOOL
209 ReferenceProviderByHandle(HANDLE Handle,
210 PCATALOG_ENTRY* Provider)
211 /*
212 * FUNCTION: Increments the reference count for a provider and returns a pointer to it
213 * ARGUMENTS:
214 * Handle = Handle for the provider
215 * Provider = Address of buffer to place pointer to provider
216 * RETURNS:
217 * TRUE if handle was valid, FALSE if not
218 */
219 {
220 PPROVIDER_HANDLE ProviderHandle;
221
222 WS_DbgPrint(MID_TRACE, ("Handle (0x%X) Provider (0x%X).\n", Handle, Provider));
223
224 EnterCriticalSection(&ProviderHandleTableLock);
225
226 ProviderHandle = GetProviderByHandle(ProviderHandleTable,
227 Handle);
228
229 WS_DbgPrint(MID_TRACE, ("ProviderHandle is %x\n", ProviderHandle));
230
231 LeaveCriticalSection(&ProviderHandleTableLock);
232
233 if (ProviderHandle)
234 {
235 ReferenceProviderByPointer(ProviderHandle->Provider);
236 *Provider = ProviderHandle->Provider;
237 }
238
239 return (ProviderHandle != NULL);
240 }
241
242
243 BOOL
244 CloseProviderHandle(HANDLE Handle)
245 {
246 PCATALOG_ENTRY Provider;
247
248 WS_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", Handle));
249
250 EnterCriticalSection(&ProviderHandleTableLock);
251
252 Provider = DeleteProviderHandle(ProviderHandleTable,
253 Handle);
254 if (!Provider)
255 return FALSE;
256
257 LeaveCriticalSection(&ProviderHandleTableLock);
258
259 DereferenceProviderByPointer(Provider);
260
261 return TRUE;
262 }
263
264
265 BOOL
266 InitProviderHandleTable(VOID)
267 {
268 ProviderHandleTable =
269 (PPROVIDER_HANDLE_BLOCK)HeapAlloc(GlobalHeap,
270 0,
271 sizeof(PROVIDER_HANDLE_BLOCK));
272 if (!ProviderHandleTable)
273 return FALSE;
274
275 WS_DbgPrint(MID_TRACE,("Called\n"));
276
277 ZeroMemory(ProviderHandleTable,
278 sizeof(PROVIDER_HANDLE_BLOCK));
279
280 InitializeListHead(&ProviderHandleTable->Entry);
281
282 InitializeCriticalSection(&ProviderHandleTableLock);
283
284 return TRUE;
285 }
286
287
288 VOID
289 FreeProviderHandleTable(VOID)
290 {
291 DeleteHandleTable(ProviderHandleTable);
292
293 DeleteCriticalSection(&ProviderHandleTableLock);
294 }
295
296 /* EOF */