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