More work on winsock stack (ping is now working)
[reactos.git] / reactos / lib / 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
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 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
74 if (Provider != NULL) {
75 DereferenceProviderByPointer(Provider);
76 Current->Handles[i].Handle = (HANDLE)0;
77 Current->Handles[i].Provider = NULL;
78 break;
79 }
80 }
81 CurrentEntry = CurrentEntry->Flink;
82 }
83 }
84
85
86 VOID
87 DeleteHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable)
88 {
89 PPROVIDER_HANDLE_BLOCK Current;
90 PLIST_ENTRY CurrentEntry;
91
92 CloseAllHandles(HandleTable);
93
94 CurrentEntry = RemoveHeadList(&HandleTable->Entry);
95
96 while (CurrentEntry != &HandleTable->Entry) {
97 Current = CONTAINING_RECORD(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
122 Provider = Entry->Provider;
123
124 if (Provider != NULL) {
125 Entry->Handle = (HANDLE)0;
126 Entry->Provider = NULL;
127 }
128
129 return Provider;
130 }
131
132
133 HANDLE
134 CreateProviderHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable,
135 HANDLE Handle,
136 PCATALOG_ENTRY Provider)
137 {
138 PPROVIDER_HANDLE_BLOCK NewBlock;
139 PLIST_ENTRY CurrentEntry;
140 ULONG i;
141
142 WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X) Provider (0x%X).\n", HandleTable, Handle, Provider));
143
144 /* Scan through the currently allocated handle blocks looking for a free slot */
145 CurrentEntry = HandleTable->Entry.Flink;
146 while (CurrentEntry != &HandleTable->Entry) {
147 PPROVIDER_HANDLE_BLOCK Block = CONTAINING_RECORD(
148 CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
149
150 for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
151 WS_DbgPrint(MAX_TRACE, ("Considering slot %ld containing 0x%X.\n", i, Block->Handles[i].Provider));
152 if (!Block->Handles[i].Provider) {
153 Block->Handles[i].Handle = Handle;
154 Block->Handles[i].Provider = Provider;
155 return Handle;
156 }
157 }
158 CurrentEntry = CurrentEntry->Flink;
159 }
160
161 /* Add a new handle block to the end of the list */
162 NewBlock = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(
163 GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK));
164
165 if (!NewBlock) {
166 return NULL;
167 }
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(HANDLE Handle,
181 PCATALOG_ENTRY Provider)
182 {
183 HANDLE h;
184
185 //EnterCriticalSection(&ProviderHandleTableLock);
186
187 h = CreateProviderHandleTable(ProviderHandleTable, Handle, Provider);
188
189 //LeaveCriticalSection(&ProviderHandleTableLock);
190
191 if (h != NULL) {
192 ReferenceProviderByPointer(Provider);
193 }
194
195 return h;
196 }
197
198
199 BOOL
200 ReferenceProviderByHandle(HANDLE Handle,
201 PCATALOG_ENTRY* Provider)
202 /*
203 * FUNCTION: Increments the reference count for a provider and returns a pointer to it
204 * ARGUMENTS:
205 * Handle = Handle for the provider
206 * Provider = Address of buffer to place pointer to provider
207 * RETURNS:
208 * TRUE if handle was valid, FALSE if not
209 */
210 {
211 PPROVIDER_HANDLE ProviderHandle;
212
213 WS_DbgPrint(MAX_TRACE, ("Handle (0x%X) Provider (0x%X).\n", Handle, Provider));
214
215 //EnterCriticalSection(&ProviderHandleTableLock);
216
217 ProviderHandle = GetProviderByHandle(ProviderHandleTable, Handle);
218
219 //LeaveCriticalSection(&ProviderHandleTableLock);
220
221 if (ProviderHandle) {
222 ReferenceProviderByPointer(ProviderHandle->Provider);
223 *Provider = ProviderHandle->Provider;
224 }
225
226 return (ProviderHandle != NULL);
227 }
228
229
230 BOOL
231 CloseProviderHandle(HANDLE Handle)
232 {
233 PCATALOG_ENTRY Provider;
234
235 WS_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", Handle));
236
237 //EnterCriticalSection(&ProviderHandleTableLock);
238
239 Provider = DeleteProviderHandle(ProviderHandleTable, Handle);
240 if (!Provider) {
241 return FALSE;
242 }
243
244 //LeaveCriticalSection(&ProviderHandleTableLock);
245
246 DereferenceProviderByPointer(Provider);
247
248 return TRUE;
249 }
250
251
252 BOOL
253 InitProviderHandleTable(VOID)
254 {
255 ProviderHandleTable = (PPROVIDER_HANDLE_BLOCK)
256 HeapAlloc(GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK));
257 if (!ProviderHandleTable) {
258 return FALSE;
259 }
260
261 ZeroMemory(ProviderHandleTable, sizeof(PROVIDER_HANDLE_BLOCK));
262
263 InitializeListHead(&ProviderHandleTable->Entry);
264
265 //InitializeCriticalSection(&ProviderHandleTableLock);
266
267 return TRUE;
268 }
269
270
271 VOID
272 FreeProviderHandleTable(VOID)
273 {
274 DeleteHandleTable(ProviderHandleTable);
275
276 //DeleteCriticalSection(&ProviderHandleTableLock);
277 }
278
279 /* EOF */