1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS WinSock 2 API
4682f85adSSerge Gautherie * FILE: dll/win32/ws2_32/src/dcatalog.c
5c2c66affSColin Finck * PURPOSE: Transport Catalog Object
6c2c66affSColin Finck * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck /* INCLUDES ******************************************************************/
10c2c66affSColin Finck
11c2c66affSColin Finck #include <ws2_32.h>
12c2c66affSColin Finck
13c2c66affSColin Finck #define NDEBUG
14c2c66affSColin Finck #include <debug.h>
15c2c66affSColin Finck
16c2c66affSColin Finck /* DATA **********************************************************************/
17c2c66affSColin Finck
18c2c66affSColin Finck #define WsTcLock() EnterCriticalSection(&Catalog->Lock)
19c2c66affSColin Finck #define WsTcUnlock() LeaveCriticalSection(&Catalog->Lock)
20c2c66affSColin Finck
21c2c66affSColin Finck /* FUNCTIONS *****************************************************************/
22c2c66affSColin Finck
23c2c66affSColin Finck PTCATALOG
24c2c66affSColin Finck WSAAPI
WsTcAllocate(VOID)25c2c66affSColin Finck WsTcAllocate(VOID)
26c2c66affSColin Finck {
27c2c66affSColin Finck PTCATALOG Catalog;
28c2c66affSColin Finck
29c2c66affSColin Finck /* Allocate the object */
30c2c66affSColin Finck Catalog = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Catalog));
31c2c66affSColin Finck
32c2c66affSColin Finck /* Return it */
33c2c66affSColin Finck return Catalog;
34c2c66affSColin Finck }
35c2c66affSColin Finck
36c2c66affSColin Finck BOOL
37c2c66affSColin Finck WSAAPI
WsTcOpen(IN PTCATALOG Catalog,IN HKEY ParentKey)38c2c66affSColin Finck WsTcOpen(IN PTCATALOG Catalog,
39c2c66affSColin Finck IN HKEY ParentKey)
40c2c66affSColin Finck {
41c2c66affSColin Finck INT ErrorCode;
42c2c66affSColin Finck DWORD CreateDisposition;
43c2c66affSColin Finck HKEY CatalogKey, NewKey;
44c2c66affSColin Finck //DWORD CatalogEntries = 0;
45c2c66affSColin Finck DWORD RegType = REG_DWORD;
46c2c66affSColin Finck DWORD RegSize = sizeof(DWORD);
47c2c66affSColin Finck DWORD UniqueId = 0;
48c2c66affSColin Finck DWORD NewData = 0;
49c2c66affSColin Finck CHAR* CatalogKeyName;
50c2c66affSColin Finck
51c2c66affSColin Finck /* Initialize the catalog lock and namespace list */
52c2c66affSColin Finck InitializeCriticalSection(&Catalog->Lock);
53c2c66affSColin Finck InitializeListHead(&Catalog->ProtocolList);
54c2c66affSColin Finck
55c2c66affSColin Finck /* Read the catalog name */
56c2c66affSColin Finck ErrorCode = RegQueryValueEx(ParentKey,
57c2c66affSColin Finck "Current_Protocol_Catalog",
58c2c66affSColin Finck 0,
59c2c66affSColin Finck &RegType,
60c2c66affSColin Finck NULL,
61c2c66affSColin Finck &RegSize);
62*af9df932SHervé Poussineau if (ErrorCode == ERROR_FILE_NOT_FOUND)
63*af9df932SHervé Poussineau {
64*af9df932SHervé Poussineau static const CHAR DefaultCatalogName[] = "Protocol_Catalog9";
65*af9df932SHervé Poussineau RegSize = sizeof(DefaultCatalogName);
66*af9df932SHervé Poussineau CatalogKeyName = HeapAlloc(WsSockHeap, 0, RegSize);
67*af9df932SHervé Poussineau memcpy(CatalogKeyName, DefaultCatalogName, RegSize);
68*af9df932SHervé Poussineau }
69*af9df932SHervé Poussineau else
70*af9df932SHervé Poussineau {
717320c989SJérôme Gardou if (ErrorCode != ERROR_SUCCESS)
727320c989SJérôme Gardou {
737320c989SJérôme Gardou DPRINT1("Failed to get protocol catalog name: %d.\n", ErrorCode);
747320c989SJérôme Gardou return FALSE;
757320c989SJérôme Gardou }
767320c989SJérôme Gardou
777320c989SJérôme Gardou if (RegType != REG_SZ)
787320c989SJérôme Gardou {
797320c989SJérôme Gardou DPRINT1("Protocol catalog name is not a string (Type %d).\n", RegType);
807320c989SJérôme Gardou return FALSE;
817320c989SJérôme Gardou }
82c2c66affSColin Finck
83c2c66affSColin Finck CatalogKeyName = HeapAlloc(WsSockHeap, 0, RegSize);
84c2c66affSColin Finck
85c2c66affSColin Finck /* Read the catalog name */
86c2c66affSColin Finck ErrorCode = RegQueryValueEx(ParentKey,
87c2c66affSColin Finck "Current_Protocol_Catalog",
88c2c66affSColin Finck 0,
89c2c66affSColin Finck &RegType,
90c2c66affSColin Finck (LPBYTE)CatalogKeyName,
91c2c66affSColin Finck &RegSize);
92c2c66affSColin Finck
93c2c66affSColin Finck /* Open the Catalog Key */
94c2c66affSColin Finck ErrorCode = RegOpenKeyEx(ParentKey,
95c2c66affSColin Finck CatalogKeyName,
96c2c66affSColin Finck 0,
97c2c66affSColin Finck MAXIMUM_ALLOWED,
98c2c66affSColin Finck &CatalogKey);
99*af9df932SHervé Poussineau }
100c2c66affSColin Finck
101c2c66affSColin Finck /* If we didn't find the key, create it */
102c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS)
103c2c66affSColin Finck {
104c2c66affSColin Finck /* Fake that we opened an existing key */
105c2c66affSColin Finck CreateDisposition = REG_OPENED_EXISTING_KEY;
106c2c66affSColin Finck }
107c2c66affSColin Finck else if (ErrorCode == ERROR_FILE_NOT_FOUND)
108c2c66affSColin Finck {
109c2c66affSColin Finck /* Create the Catalog Name */
110c2c66affSColin Finck ErrorCode = RegCreateKeyEx(ParentKey,
111c2c66affSColin Finck CatalogKeyName,
112c2c66affSColin Finck 0,
113c2c66affSColin Finck NULL,
114c2c66affSColin Finck REG_OPTION_NON_VOLATILE,
115c2c66affSColin Finck KEY_ALL_ACCESS,
116c2c66affSColin Finck NULL,
117c2c66affSColin Finck &CatalogKey,
118c2c66affSColin Finck &CreateDisposition);
119c2c66affSColin Finck }
120c2c66affSColin Finck
121c2c66affSColin Finck HeapFree(WsSockHeap, 0, CatalogKeyName);
122c2c66affSColin Finck RegType = REG_DWORD;
123c2c66affSColin Finck RegSize = sizeof(DWORD);
124c2c66affSColin Finck
125c2c66affSColin Finck /* Fail if that didn't work */
126c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS) return FALSE;
127c2c66affSColin Finck
128c2c66affSColin Finck /* Check if we had to create the key */
129c2c66affSColin Finck if (CreateDisposition == REG_CREATED_NEW_KEY)
130c2c66affSColin Finck {
131c2c66affSColin Finck /* Write the count of entries (0 now) */
132c2c66affSColin Finck ErrorCode = RegSetValueEx(CatalogKey,
133c2c66affSColin Finck "Num_Catalog_Entries",
134c2c66affSColin Finck 0,
135c2c66affSColin Finck REG_DWORD,
136c2c66affSColin Finck (LPBYTE)&NewData,
137c2c66affSColin Finck sizeof(NewData));
138c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
139c2c66affSColin Finck {
140c2c66affSColin Finck /* Close the key and fail */
141c2c66affSColin Finck RegCloseKey(CatalogKey);
142c2c66affSColin Finck return FALSE;
143c2c66affSColin Finck }
144c2c66affSColin Finck
145c2c66affSColin Finck /* Write the first catalog entry ID */
146c2c66affSColin Finck NewData = 1001;
147c2c66affSColin Finck ErrorCode = RegSetValueEx(CatalogKey,
148c2c66affSColin Finck "Next_Catalog_Entry_ID",
149c2c66affSColin Finck 0,
150c2c66affSColin Finck REG_DWORD,
151c2c66affSColin Finck (LPBYTE)&NewData,
152c2c66affSColin Finck sizeof(NewData));
153c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
154c2c66affSColin Finck {
155c2c66affSColin Finck /* Close the key and fail */
156c2c66affSColin Finck RegCloseKey(CatalogKey);
157c2c66affSColin Finck return FALSE;
158c2c66affSColin Finck }
159c2c66affSColin Finck
160c2c66affSColin Finck /* Write the first catalog entry Uniqe ID */
161c2c66affSColin Finck NewData = 1;
162c2c66affSColin Finck ErrorCode = RegSetValueEx(CatalogKey,
163c2c66affSColin Finck "Serial_Access_Num",
164c2c66affSColin Finck 0,
165c2c66affSColin Finck REG_DWORD,
166c2c66affSColin Finck (LPBYTE)&NewData,
167c2c66affSColin Finck sizeof(NewData));
168c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
169c2c66affSColin Finck {
170c2c66affSColin Finck /* Close the key and fail */
171c2c66affSColin Finck RegCloseKey(CatalogKey);
172c2c66affSColin Finck return FALSE;
173c2c66affSColin Finck }
174c2c66affSColin Finck
175c2c66affSColin Finck /* Create a key for this entry */
176c2c66affSColin Finck ErrorCode = RegCreateKeyEx(CatalogKey,
177c2c66affSColin Finck "Catalog_Entries",
178c2c66affSColin Finck 0,
179c2c66affSColin Finck NULL,
180c2c66affSColin Finck REG_OPTION_NON_VOLATILE,
181c2c66affSColin Finck KEY_ALL_ACCESS,
182c2c66affSColin Finck NULL,
183c2c66affSColin Finck &NewKey,
184c2c66affSColin Finck &CreateDisposition);
185c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
186c2c66affSColin Finck {
187c2c66affSColin Finck /* Close the key and fail */
188c2c66affSColin Finck RegCloseKey(CatalogKey);
189c2c66affSColin Finck return FALSE;
190c2c66affSColin Finck }
191c2c66affSColin Finck
192c2c66affSColin Finck /* Close the key since we don't need it */
193c2c66affSColin Finck RegCloseKey(NewKey);
194c2c66affSColin Finck }
195c2c66affSColin Finck else
196c2c66affSColin Finck {
197c2c66affSColin Finck RegSize = sizeof(DWORD);
198c2c66affSColin Finck /* Read the serial number */
199c2c66affSColin Finck ErrorCode = RegQueryValueEx(CatalogKey,
200c2c66affSColin Finck "Serial_Access_Num",
201c2c66affSColin Finck 0,
202c2c66affSColin Finck &RegType,
203c2c66affSColin Finck (LPBYTE)&UniqueId,
204c2c66affSColin Finck &RegSize);
205c2c66affSColin Finck
206c2c66affSColin Finck /* Check if it's missing for some reason */
207c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
208c2c66affSColin Finck {
209c2c66affSColin Finck /* Write the first catalog entry Unique ID */
210c2c66affSColin Finck NewData = 1;
211c2c66affSColin Finck ErrorCode = RegSetValueEx(CatalogKey,
212c2c66affSColin Finck "Serial_Access_Num",
213c2c66affSColin Finck 0,
214c2c66affSColin Finck REG_DWORD,
215c2c66affSColin Finck (LPBYTE)&NewData,
216c2c66affSColin Finck sizeof(NewData));
217c2c66affSColin Finck }
218c2c66affSColin Finck }
219c2c66affSColin Finck
220c2c66affSColin Finck /* Set the Catalog Key */
221c2c66affSColin Finck Catalog->CatalogKey = CatalogKey;
222c2c66affSColin Finck return TRUE;
223c2c66affSColin Finck }
224c2c66affSColin Finck
225c2c66affSColin Finck DWORD
226c2c66affSColin Finck WSAAPI
WsTcInitializeFromRegistry(IN PTCATALOG Catalog,IN HKEY ParentKey,IN HANDLE CatalogEvent)227c2c66affSColin Finck WsTcInitializeFromRegistry(IN PTCATALOG Catalog,
228c2c66affSColin Finck IN HKEY ParentKey,
229c2c66affSColin Finck IN HANDLE CatalogEvent)
230c2c66affSColin Finck {
231c2c66affSColin Finck INT ErrorCode = WSASYSCALLFAILURE;
232c2c66affSColin Finck
233c2c66affSColin Finck /* Open the catalog */
234c2c66affSColin Finck if (WsTcOpen(Catalog, ParentKey))
235c2c66affSColin Finck {
236c2c66affSColin Finck /* Refresh it */
237c2c66affSColin Finck ErrorCode = WsTcRefreshFromRegistry(Catalog, CatalogEvent);
238c2c66affSColin Finck }
239c2c66affSColin Finck
240c2c66affSColin Finck /* Return the status */
241c2c66affSColin Finck return ErrorCode;
242c2c66affSColin Finck }
243c2c66affSColin Finck
244c2c66affSColin Finck DWORD
245c2c66affSColin Finck WSAAPI
WsTcRefreshFromRegistry(IN PTCATALOG Catalog,IN HANDLE CatalogEvent)246c2c66affSColin Finck WsTcRefreshFromRegistry(IN PTCATALOG Catalog,
247c2c66affSColin Finck IN HANDLE CatalogEvent)
248c2c66affSColin Finck {
249c2c66affSColin Finck INT ErrorCode;
250c2c66affSColin Finck BOOLEAN LocalEvent = FALSE;
251c2c66affSColin Finck LIST_ENTRY LocalList;
252c2c66affSColin Finck DWORD UniqueId;
253c2c66affSColin Finck HKEY EntriesKey;
254c2c66affSColin Finck DWORD CatalogEntries;
255c2c66affSColin Finck PTCATALOG_ENTRY CatalogEntry;
256c2c66affSColin Finck DWORD NextCatalogEntry;
257c2c66affSColin Finck BOOL NewChangesMade;
258c2c66affSColin Finck PLIST_ENTRY Entry;
259c2c66affSColin Finck DWORD RegType = REG_DWORD;
260c2c66affSColin Finck DWORD RegSize = sizeof(DWORD);
261c2c66affSColin Finck DWORD i;
262c2c66affSColin Finck
263c2c66affSColin Finck /* Check if we got an event */
264c2c66affSColin Finck if (!CatalogEvent)
265c2c66affSColin Finck {
266c2c66affSColin Finck /* Create an event ourselves */
267c2c66affSColin Finck CatalogEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
268c2c66affSColin Finck if (!CatalogEvent) return WSASYSCALLFAILURE;
269c2c66affSColin Finck LocalEvent = TRUE;
270c2c66affSColin Finck }
271c2c66affSColin Finck
272c2c66affSColin Finck /* Lock the catalog */
273c2c66affSColin Finck WsTcLock();
274c2c66affSColin Finck
275c2c66affSColin Finck /* Initialize our local list for the loop */
276c2c66affSColin Finck InitializeListHead(&LocalList);
277c2c66affSColin Finck
278c2c66affSColin Finck /* Start looping */
279c2c66affSColin Finck do
280c2c66affSColin Finck {
281c2c66affSColin Finck /* Setup notifications for the catalog entry */
282c2c66affSColin Finck ErrorCode = WsSetupCatalogProtection(Catalog->CatalogKey,
283c2c66affSColin Finck CatalogEvent,
284c2c66affSColin Finck &UniqueId);
285c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS) break;
286c2c66affSColin Finck
287c2c66affSColin Finck /* Check if we've changed till now */
288c2c66affSColin Finck if (UniqueId == Catalog->UniqueId)
289c2c66affSColin Finck {
290c2c66affSColin Finck /* We haven't, so return */
291c2c66affSColin Finck ErrorCode = ERROR_SUCCESS;
292c2c66affSColin Finck break;
293c2c66affSColin Finck }
294c2c66affSColin Finck
295c2c66affSColin Finck /* Now Open the Entries */
296c2c66affSColin Finck ErrorCode = RegOpenKeyEx(Catalog->CatalogKey,
297c2c66affSColin Finck "Catalog_Entries",
298c2c66affSColin Finck 0,
299c2c66affSColin Finck MAXIMUM_ALLOWED,
300c2c66affSColin Finck &EntriesKey);
301c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
302c2c66affSColin Finck {
303c2c66affSColin Finck /* Critical failure */
304c2c66affSColin Finck ErrorCode = WSASYSCALLFAILURE;
305c2c66affSColin Finck break;
306c2c66affSColin Finck }
307c2c66affSColin Finck
308c2c66affSColin Finck /* Get the next entry */
309c2c66affSColin Finck ErrorCode = RegQueryValueEx(Catalog->CatalogKey,
310c2c66affSColin Finck "Next_Catalog_Entry_ID",
311c2c66affSColin Finck 0,
312c2c66affSColin Finck &RegType,
313c2c66affSColin Finck (LPBYTE)&NextCatalogEntry,
314c2c66affSColin Finck &RegSize);
315c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
316c2c66affSColin Finck {
317c2c66affSColin Finck /* Critical failure */
318c2c66affSColin Finck ErrorCode = WSASYSCALLFAILURE;
319c2c66affSColin Finck break;
320c2c66affSColin Finck }
321c2c66affSColin Finck
322c2c66affSColin Finck /* Find out how many there are */
323c2c66affSColin Finck ErrorCode = RegQueryValueEx(Catalog->CatalogKey,
324c2c66affSColin Finck "Num_Catalog_Entries",
325c2c66affSColin Finck 0,
326c2c66affSColin Finck &RegType,
327c2c66affSColin Finck (LPBYTE)&CatalogEntries,
328c2c66affSColin Finck &RegSize);
329c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
330c2c66affSColin Finck {
331c2c66affSColin Finck /* Critical failure */
332c2c66affSColin Finck ErrorCode = WSASYSCALLFAILURE;
333c2c66affSColin Finck break;
334c2c66affSColin Finck }
335c2c66affSColin Finck
336c2c66affSColin Finck /* Initialize them all */
337c2c66affSColin Finck for (i = 1; i <= CatalogEntries; i++)
338c2c66affSColin Finck {
339c2c66affSColin Finck /* Allocate a Catalog Entry Structure */
340c2c66affSColin Finck CatalogEntry = WsTcEntryAllocate();
341c2c66affSColin Finck if (!CatalogEntry)
342c2c66affSColin Finck {
343c2c66affSColin Finck /* Not enough memory, fail */
344c2c66affSColin Finck ErrorCode = WSA_NOT_ENOUGH_MEMORY;
345c2c66affSColin Finck break;
346c2c66affSColin Finck }
347c2c66affSColin Finck
348c2c66affSColin Finck /* Initialize it from the Registry Key */
349c2c66affSColin Finck ErrorCode = WsTcEntryInitializeFromRegistry(CatalogEntry,
350c2c66affSColin Finck EntriesKey,
351c2c66affSColin Finck i);
352c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
353c2c66affSColin Finck {
354c2c66affSColin Finck /* We failed to get it, dereference the entry and leave */
355c2c66affSColin Finck WsTcEntryDereference(CatalogEntry);
356c2c66affSColin Finck break;
357c2c66affSColin Finck }
358c2c66affSColin Finck
359c2c66affSColin Finck /* Insert it to our List */
360c2c66affSColin Finck InsertTailList(&LocalList, &CatalogEntry->CatalogLink);
361c2c66affSColin Finck }
362c2c66affSColin Finck
363c2c66affSColin Finck /* Close the catalog key */
364c2c66affSColin Finck RegCloseKey(EntriesKey);
365c2c66affSColin Finck
366c2c66affSColin Finck /* Check if we changed during our read and if we have success */
367c2c66affSColin Finck NewChangesMade = WsCheckCatalogState(CatalogEvent);
368c2c66affSColin Finck if (!NewChangesMade && ErrorCode == ERROR_SUCCESS)
369c2c66affSColin Finck {
370c2c66affSColin Finck /* All is good, update the protocol list */
371c2c66affSColin Finck WsTcUpdateProtocolList(Catalog, &LocalList);
372c2c66affSColin Finck
373c2c66affSColin Finck /* Update and return */
374c2c66affSColin Finck Catalog->UniqueId = UniqueId;
375c2c66affSColin Finck Catalog->NextId = NextCatalogEntry;
376c2c66affSColin Finck break;
377c2c66affSColin Finck }
378c2c66affSColin Finck
379c2c66affSColin Finck /* We failed and/or catalog data changed, free what we did till now */
380c2c66affSColin Finck while (!IsListEmpty(&LocalList))
381c2c66affSColin Finck {
382c2c66affSColin Finck /* Get the LP Catalog Item */
383c2c66affSColin Finck Entry = RemoveHeadList(&LocalList);
384c2c66affSColin Finck CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
385c2c66affSColin Finck
386c2c66affSColin Finck /* Dereference it */
387c2c66affSColin Finck WsTcEntryDereference(CatalogEntry);
388c2c66affSColin Finck }
389c2c66affSColin Finck } while (NewChangesMade);
390c2c66affSColin Finck
391c2c66affSColin Finck /* Release the lock */
392c2c66affSColin Finck WsTcUnlock();
393c2c66affSColin Finck
394c2c66affSColin Finck /* Close the event, if any was created by us */
395c2c66affSColin Finck if (LocalEvent) CloseHandle(CatalogEvent);
396c2c66affSColin Finck
397c2c66affSColin Finck /* All Done */
398c2c66affSColin Finck return ErrorCode;
399c2c66affSColin Finck }
400c2c66affSColin Finck
401c2c66affSColin Finck DWORD
402c2c66affSColin Finck WSAAPI
WsTcGetEntryFromAf(IN PTCATALOG Catalog,IN INT AddressFamily,IN PTCATALOG_ENTRY * CatalogEntry)403c2c66affSColin Finck WsTcGetEntryFromAf(IN PTCATALOG Catalog,
404c2c66affSColin Finck IN INT AddressFamily,
405c2c66affSColin Finck IN PTCATALOG_ENTRY *CatalogEntry)
406c2c66affSColin Finck {
407c2c66affSColin Finck INT ErrorCode = WSAEINVAL;
408c2c66affSColin Finck PLIST_ENTRY NextEntry;
409c2c66affSColin Finck PTCATALOG_ENTRY Entry;
410c2c66affSColin Finck
411c2c66affSColin Finck /* Assume failure */
412c2c66affSColin Finck *CatalogEntry = NULL;
413c2c66affSColin Finck
414c2c66affSColin Finck /* Lock the catalog */
415c2c66affSColin Finck WsTcLock();
416c2c66affSColin Finck
417c2c66affSColin Finck /* Match the Id with all the entries in the List */
418c2c66affSColin Finck NextEntry = Catalog->ProtocolList.Flink;
419c2c66affSColin Finck while (NextEntry != &Catalog->ProtocolList)
420c2c66affSColin Finck {
421c2c66affSColin Finck /* Get the Current Entry */
422c2c66affSColin Finck Entry = CONTAINING_RECORD(NextEntry, TCATALOG_ENTRY, CatalogLink);
423c2c66affSColin Finck NextEntry = NextEntry->Flink;
424c2c66affSColin Finck
425c2c66affSColin Finck /* Check if this is the Catalog Entry ID we want */
426c2c66affSColin Finck if (Entry->ProtocolInfo.iAddressFamily == AddressFamily)
427c2c66affSColin Finck {
428c2c66affSColin Finck /* Check if it doesn't already have a provider */
429c2c66affSColin Finck if (!Entry->Provider)
430c2c66affSColin Finck {
431c2c66affSColin Finck /* Match, load the Provider */
432c2c66affSColin Finck ErrorCode = WsTcLoadProvider(Catalog, Entry);
433c2c66affSColin Finck
434c2c66affSColin Finck /* Make sure this didn't fail */
435c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS) break;
436c2c66affSColin Finck }
437c2c66affSColin Finck
438c2c66affSColin Finck /* Reference the entry and return it */
439c2c66affSColin Finck InterlockedIncrement(&Entry->RefCount);
440c2c66affSColin Finck *CatalogEntry = Entry;
441c2c66affSColin Finck ErrorCode = ERROR_SUCCESS;
442c2c66affSColin Finck break;
443c2c66affSColin Finck }
444c2c66affSColin Finck }
445c2c66affSColin Finck
446c2c66affSColin Finck /* Release the catalog */
447c2c66affSColin Finck WsTcUnlock();
448c2c66affSColin Finck
449c2c66affSColin Finck /* Return */
450c2c66affSColin Finck return ErrorCode;
451c2c66affSColin Finck }
452c2c66affSColin Finck
453c2c66affSColin Finck DWORD
454c2c66affSColin Finck WSAAPI
WsTcGetEntryFromCatalogEntryId(IN PTCATALOG Catalog,IN DWORD CatalogEntryId,IN PTCATALOG_ENTRY * CatalogEntry)455c2c66affSColin Finck WsTcGetEntryFromCatalogEntryId(IN PTCATALOG Catalog,
456c2c66affSColin Finck IN DWORD CatalogEntryId,
457c2c66affSColin Finck IN PTCATALOG_ENTRY *CatalogEntry)
458c2c66affSColin Finck {
459c2c66affSColin Finck INT ErrorCode = WSAEINVAL;
460c2c66affSColin Finck PLIST_ENTRY NextEntry;
461c2c66affSColin Finck PTCATALOG_ENTRY Entry;
462c2c66affSColin Finck
463c2c66affSColin Finck /* Lock the catalog */
464c2c66affSColin Finck WsTcLock();
465c2c66affSColin Finck
466c2c66affSColin Finck /* Match the Id with all the entries in the List */
467c2c66affSColin Finck NextEntry = Catalog->ProtocolList.Flink;
468c2c66affSColin Finck while (NextEntry != &Catalog->ProtocolList)
469c2c66affSColin Finck {
470c2c66affSColin Finck /* Get the Current Entry */
471c2c66affSColin Finck Entry = CONTAINING_RECORD(NextEntry, TCATALOG_ENTRY, CatalogLink);
472c2c66affSColin Finck NextEntry = NextEntry->Flink;
473c2c66affSColin Finck
474c2c66affSColin Finck /* Check if this is the Catalog Entry ID we want */
475c2c66affSColin Finck if (Entry->ProtocolInfo.dwCatalogEntryId == CatalogEntryId)
476c2c66affSColin Finck {
477c2c66affSColin Finck /* Check if it doesn't already have a provider */
478c2c66affSColin Finck if (!Entry->Provider)
479c2c66affSColin Finck {
480c2c66affSColin Finck /* Match, load the Provider */
481c2c66affSColin Finck WsTcLoadProvider(Catalog, Entry);
482c2c66affSColin Finck }
483c2c66affSColin Finck
484c2c66affSColin Finck /* Reference the entry and return it */
485c2c66affSColin Finck InterlockedIncrement(&Entry->RefCount);
486c2c66affSColin Finck *CatalogEntry = Entry;
487c2c66affSColin Finck ErrorCode = ERROR_SUCCESS;
488c2c66affSColin Finck break;
489c2c66affSColin Finck }
490c2c66affSColin Finck }
491c2c66affSColin Finck
492c2c66affSColin Finck /* Release the catalog */
493c2c66affSColin Finck WsTcUnlock();
494c2c66affSColin Finck
495c2c66affSColin Finck /* Return */
496c2c66affSColin Finck return ErrorCode;
497c2c66affSColin Finck }
498c2c66affSColin Finck
499c2c66affSColin Finck DWORD
500c2c66affSColin Finck WSAAPI
WsTcGetEntryFromTriplet(IN PTCATALOG Catalog,IN INT af,IN INT type,IN INT protocol,IN DWORD StartId,IN PTCATALOG_ENTRY * CatalogEntry)501c2c66affSColin Finck WsTcGetEntryFromTriplet(IN PTCATALOG Catalog,
502c2c66affSColin Finck IN INT af,
503c2c66affSColin Finck IN INT type,
504c2c66affSColin Finck IN INT protocol,
505c2c66affSColin Finck IN DWORD StartId,
506c2c66affSColin Finck IN PTCATALOG_ENTRY *CatalogEntry)
507c2c66affSColin Finck {
508c2c66affSColin Finck INT ErrorCode = WSAEINVAL;
509c2c66affSColin Finck PLIST_ENTRY NextEntry;
510c2c66affSColin Finck PTCATALOG_ENTRY Entry;
511c2c66affSColin Finck DPRINT("WsTcGetEntryFromTriplet: %lx, %lx, %lx, %lx\n", af, type, protocol, StartId);
512c2c66affSColin Finck
513c2c66affSColin Finck /* Assume failure */
514c2c66affSColin Finck *CatalogEntry = NULL;
515c2c66affSColin Finck
516c2c66affSColin Finck /* Lock the catalog */
517c2c66affSColin Finck WsTcLock();
518c2c66affSColin Finck
519c2c66affSColin Finck NextEntry = Catalog->ProtocolList.Flink;
520c2c66affSColin Finck
521c2c66affSColin Finck /* Check if we are starting past 0 */
522c2c66affSColin Finck if (StartId)
523c2c66affSColin Finck {
524c2c66affSColin Finck /* Loop the list */
525c2c66affSColin Finck while (NextEntry != &Catalog->ProtocolList)
526c2c66affSColin Finck {
527c2c66affSColin Finck /* Get the Current Entry */
528c2c66affSColin Finck Entry = CONTAINING_RECORD(NextEntry, TCATALOG_ENTRY, CatalogLink);
529c2c66affSColin Finck NextEntry = NextEntry->Flink;
530c2c66affSColin Finck
531c2c66affSColin Finck /* Check if this is the ID where we are starting */
532c2c66affSColin Finck if (Entry->ProtocolInfo.dwCatalogEntryId == StartId) break;
533c2c66affSColin Finck }
534c2c66affSColin Finck }
535c2c66affSColin Finck
536c2c66affSColin Finck /* Match the Id with all the entries in the List */
537c2c66affSColin Finck while (NextEntry != &Catalog->ProtocolList)
538c2c66affSColin Finck {
539c2c66affSColin Finck /* Get the Current Entry */
540c2c66affSColin Finck Entry = CONTAINING_RECORD(NextEntry, TCATALOG_ENTRY, CatalogLink);
541c2c66affSColin Finck NextEntry = NextEntry->Flink;
542c2c66affSColin Finck
543c2c66affSColin Finck /* Check if Address Family Matches or if it's wildcard */
544c2c66affSColin Finck if ((Entry->ProtocolInfo.iAddressFamily == af) || (af == AF_UNSPEC))
545c2c66affSColin Finck {
546c2c66affSColin Finck /* Check if Socket Type Matches or if it's wildcard */
547c2c66affSColin Finck if ((Entry->ProtocolInfo.iSocketType == type) || (type == 0))
548c2c66affSColin Finck {
549c2c66affSColin Finck /* Check if Protocol is In Range or if it's wildcard */
550c2c66affSColin Finck if (((Entry->ProtocolInfo.iProtocol <= protocol) &&
551c2c66affSColin Finck ((Entry->ProtocolInfo.iProtocol +
552c2c66affSColin Finck Entry->ProtocolInfo.iProtocolMaxOffset) >= protocol)) ||
553c2c66affSColin Finck (protocol == 0))
554c2c66affSColin Finck {
555c2c66affSColin Finck /* Check if it doesn't already have a provider */
556c2c66affSColin Finck if (!Entry->Provider)
557c2c66affSColin Finck {
558c2c66affSColin Finck /* Match, load the Provider */
559c2c66affSColin Finck ErrorCode = WsTcLoadProvider(Catalog, Entry);
560c2c66affSColin Finck
561c2c66affSColin Finck /* Make sure this didn't fail */
562c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS) break;
563c2c66affSColin Finck }
564c2c66affSColin Finck
565c2c66affSColin Finck /* Reference the entry and return it */
566c2c66affSColin Finck InterlockedIncrement(&Entry->RefCount);
567c2c66affSColin Finck *CatalogEntry = Entry;
568c2c66affSColin Finck ErrorCode = ERROR_SUCCESS;
569c2c66affSColin Finck break;
570c2c66affSColin Finck }
571c2c66affSColin Finck else
572c2c66affSColin Finck {
573c2c66affSColin Finck ErrorCode = WSAEPROTONOSUPPORT;
574c2c66affSColin Finck }
575c2c66affSColin Finck }
576c2c66affSColin Finck else
577c2c66affSColin Finck {
578c2c66affSColin Finck ErrorCode = WSAESOCKTNOSUPPORT;
579c2c66affSColin Finck }
580c2c66affSColin Finck }
581c2c66affSColin Finck else
582c2c66affSColin Finck {
583c2c66affSColin Finck ErrorCode = WSAEAFNOSUPPORT;
584c2c66affSColin Finck }
585c2c66affSColin Finck }
586c2c66affSColin Finck
587c2c66affSColin Finck /* Release the catalog */
588c2c66affSColin Finck WsTcUnlock();
589c2c66affSColin Finck
590c2c66affSColin Finck /* Return */
591c2c66affSColin Finck return ErrorCode;
592c2c66affSColin Finck }
593c2c66affSColin Finck
594c2c66affSColin Finck PTPROVIDER
595c2c66affSColin Finck WSAAPI
WsTcFindProvider(IN PTCATALOG Catalog,IN LPGUID ProviderId)596c2c66affSColin Finck WsTcFindProvider(IN PTCATALOG Catalog,
597c2c66affSColin Finck IN LPGUID ProviderId)
598c2c66affSColin Finck {
599c2c66affSColin Finck PTPROVIDER Provider;
600c2c66affSColin Finck PLIST_ENTRY Entry;
601c2c66affSColin Finck PTCATALOG_ENTRY CatalogEntry;
602c2c66affSColin Finck
603c2c66affSColin Finck /* Loop the provider list */
604c2c66affSColin Finck Entry = Catalog->ProtocolList.Flink;
605c2c66affSColin Finck while (Entry != &Catalog->ProtocolList)
606c2c66affSColin Finck {
607c2c66affSColin Finck /* Get the entry */
608c2c66affSColin Finck CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
609c2c66affSColin Finck
610c2c66affSColin Finck /* Move to the next one, get the provider */
611c2c66affSColin Finck Entry = Entry->Flink;
612c2c66affSColin Finck Provider = CatalogEntry->Provider;
613c2c66affSColin Finck
614c2c66affSColin Finck /* Check for a match */
615c2c66affSColin Finck if (Provider &&
616c2c66affSColin Finck IsEqualGUID(&CatalogEntry->ProtocolInfo.ProviderId, ProviderId))
617c2c66affSColin Finck {
618c2c66affSColin Finck /* Found a match */
619c2c66affSColin Finck return Provider;
620c2c66affSColin Finck }
621c2c66affSColin Finck }
622c2c66affSColin Finck
623c2c66affSColin Finck /* No match here */
624c2c66affSColin Finck return NULL;
625c2c66affSColin Finck }
626c2c66affSColin Finck
627c2c66affSColin Finck DWORD
628c2c66affSColin Finck WSAAPI
WsTcLoadProvider(IN PTCATALOG Catalog,IN PTCATALOG_ENTRY CatalogEntry)629c2c66affSColin Finck WsTcLoadProvider(IN PTCATALOG Catalog,
630c2c66affSColin Finck IN PTCATALOG_ENTRY CatalogEntry)
631c2c66affSColin Finck {
632c2c66affSColin Finck INT ErrorCode = ERROR_SUCCESS;
633c2c66affSColin Finck PTPROVIDER Provider;
634c2c66affSColin Finck DPRINT("WsTcLoadProvider: %p, %p\n", Catalog, CatalogEntry);
635c2c66affSColin Finck
636c2c66affSColin Finck /* Lock the catalog */
637c2c66affSColin Finck WsTcLock();
638c2c66affSColin Finck
639c2c66affSColin Finck /* Check if we have a provider already */
640c2c66affSColin Finck if (!CatalogEntry->Provider)
641c2c66affSColin Finck {
642c2c66affSColin Finck /* Try to find another instance */
643c2c66affSColin Finck Provider = WsTcFindProvider(Catalog,
644c2c66affSColin Finck &CatalogEntry->ProtocolInfo.ProviderId);
645c2c66affSColin Finck
646c2c66affSColin Finck /* Check if we found one now */
647c2c66affSColin Finck if (Provider)
648c2c66affSColin Finck {
649c2c66affSColin Finck /* Set this one as the provider */
650c2c66affSColin Finck WsTcEntrySetProvider(CatalogEntry, Provider);
651c2c66affSColin Finck ErrorCode = ERROR_SUCCESS;
652c2c66affSColin Finck }
653c2c66affSColin Finck else
654c2c66affSColin Finck {
655c2c66affSColin Finck /* Nothing found, Allocate a provider */
656c2c66affSColin Finck if ((Provider = WsTpAllocate()))
657c2c66affSColin Finck {
658c2c66affSColin Finck /* Initialize it */
659c2c66affSColin Finck ErrorCode = WsTpInitialize(Provider,
660c2c66affSColin Finck CatalogEntry->DllPath,
661c2c66affSColin Finck &CatalogEntry->ProtocolInfo);
662c2c66affSColin Finck
663c2c66affSColin Finck /* Ensure success */
664c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS)
665c2c66affSColin Finck {
666c2c66affSColin Finck /* Set the provider */
667c2c66affSColin Finck WsTcEntrySetProvider(CatalogEntry, Provider);
668c2c66affSColin Finck }
669c2c66affSColin Finck
670c2c66affSColin Finck /* Dereference it */
671c2c66affSColin Finck WsTpDereference(Provider);
672c2c66affSColin Finck }
673c2c66affSColin Finck else
674c2c66affSColin Finck {
675c2c66affSColin Finck /* No memory */
676c2c66affSColin Finck ErrorCode = WSA_NOT_ENOUGH_MEMORY;
677c2c66affSColin Finck }
678c2c66affSColin Finck }
679c2c66affSColin Finck }
680c2c66affSColin Finck
681c2c66affSColin Finck /* Release the lock */
682c2c66affSColin Finck WsTcUnlock();
683c2c66affSColin Finck return ErrorCode;
684c2c66affSColin Finck }
685c2c66affSColin Finck
686c2c66affSColin Finck VOID
687c2c66affSColin Finck WSAAPI
WsTcUpdateProtocolList(IN PTCATALOG Catalog,IN PLIST_ENTRY List)688c2c66affSColin Finck WsTcUpdateProtocolList(IN PTCATALOG Catalog,
689c2c66affSColin Finck IN PLIST_ENTRY List)
690c2c66affSColin Finck {
691c2c66affSColin Finck LIST_ENTRY TempList;
692c2c66affSColin Finck PTCATALOG_ENTRY CatalogEntry, OldCatalogEntry;
693c2c66affSColin Finck PLIST_ENTRY Entry;
694c2c66affSColin Finck
695c2c66affSColin Finck /* First move from our list to the old one */
696c2c66affSColin Finck InsertHeadList(&Catalog->ProtocolList, &TempList);
697c2c66affSColin Finck RemoveEntryList(&Catalog->ProtocolList);
698c2c66affSColin Finck InitializeListHead(&Catalog->ProtocolList);
699c2c66affSColin Finck
700c2c66affSColin Finck /* Loop every item in the list */
701c2c66affSColin Finck while (!IsListEmpty(List))
702c2c66affSColin Finck {
703c2c66affSColin Finck /* Get the catalog entry */
704c2c66affSColin Finck Entry = RemoveHeadList(List);
705c2c66affSColin Finck CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
706c2c66affSColin Finck
707c2c66affSColin Finck /* Check if this item is already in our list */
708c2c66affSColin Finck Entry = TempList.Flink;
709c2c66affSColin Finck while (Entry != &TempList)
710c2c66affSColin Finck {
711c2c66affSColin Finck /* Get the catalog entry */
712c2c66affSColin Finck OldCatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
713c2c66affSColin Finck Entry = Entry->Flink;
714c2c66affSColin Finck
715c2c66affSColin Finck /* Check if they match */
716c2c66affSColin Finck if (CatalogEntry->ProtocolInfo.dwCatalogEntryId ==
717c2c66affSColin Finck OldCatalogEntry->ProtocolInfo.dwCatalogEntryId)
718c2c66affSColin Finck {
719c2c66affSColin Finck /* We have a match, use the old item instead */
720c2c66affSColin Finck WsTcEntryDereference(CatalogEntry);
721c2c66affSColin Finck CatalogEntry = OldCatalogEntry;
722c2c66affSColin Finck RemoveEntryList(&CatalogEntry->CatalogLink);
723c2c66affSColin Finck
724c2c66affSColin Finck /* Decrease the number of protocols we have */
725c2c66affSColin Finck Catalog->ItemCount--;
726c2c66affSColin Finck break;
727c2c66affSColin Finck }
728c2c66affSColin Finck }
729c2c66affSColin Finck
730c2c66affSColin Finck /* Add this item */
731c2c66affSColin Finck InsertTailList(&Catalog->ProtocolList, &CatalogEntry->CatalogLink);
732c2c66affSColin Finck Catalog->ItemCount++;
733c2c66affSColin Finck }
734c2c66affSColin Finck
735c2c66affSColin Finck /* If there's anything left in the temporary list */
736c2c66affSColin Finck while (!IsListEmpty(&TempList))
737c2c66affSColin Finck {
738c2c66affSColin Finck /* Get the entry */
739c2c66affSColin Finck Entry = RemoveHeadList(&TempList);
740c2c66affSColin Finck CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
741c2c66affSColin Finck
742c2c66affSColin Finck /* Remove it */
743c2c66affSColin Finck Catalog->ItemCount--;
744c2c66affSColin Finck WsTcEntryDereference(CatalogEntry);
745c2c66affSColin Finck }
746c2c66affSColin Finck }
747c2c66affSColin Finck
748c2c66affSColin Finck VOID
749c2c66affSColin Finck WSAAPI
WsTcEnumerateCatalogItems(IN PTCATALOG Catalog,IN PTCATALOG_ENUMERATE_PROC Callback,IN PVOID Context)750c2c66affSColin Finck WsTcEnumerateCatalogItems(IN PTCATALOG Catalog,
751c2c66affSColin Finck IN PTCATALOG_ENUMERATE_PROC Callback,
752c2c66affSColin Finck IN PVOID Context)
753c2c66affSColin Finck {
754c2c66affSColin Finck PLIST_ENTRY Entry;
755c2c66affSColin Finck PTCATALOG_ENTRY CatalogEntry;
756c2c66affSColin Finck BOOL GoOn = TRUE;
757c2c66affSColin Finck
758c2c66affSColin Finck /* Lock the catalog */
759c2c66affSColin Finck WsTcLock();
760c2c66affSColin Finck
761c2c66affSColin Finck /* Loop the entries */
762c2c66affSColin Finck Entry = Catalog->ProtocolList.Flink;
763c2c66affSColin Finck while (GoOn && (Entry != &Catalog->ProtocolList))
764c2c66affSColin Finck {
765c2c66affSColin Finck /* Get the entry */
766c2c66affSColin Finck CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
767c2c66affSColin Finck
768c2c66affSColin Finck /* Move to the next one and call the callback */
769c2c66affSColin Finck Entry = Entry->Flink;
770c2c66affSColin Finck GoOn = Callback(Context, CatalogEntry);
771c2c66affSColin Finck }
772c2c66affSColin Finck
773c2c66affSColin Finck /* Release lock */
774c2c66affSColin Finck WsTcUnlock();
775c2c66affSColin Finck }
776c2c66affSColin Finck
777c2c66affSColin Finck DWORD
778c2c66affSColin Finck WSAAPI
WsTcFindIfsProviderForSocket(IN PTCATALOG Catalog,IN SOCKET Handle)779c2c66affSColin Finck WsTcFindIfsProviderForSocket(IN PTCATALOG Catalog,
780c2c66affSColin Finck IN SOCKET Handle)
781c2c66affSColin Finck {
782c2c66affSColin Finck PTPROVIDER Provider;
783c2c66affSColin Finck IN SOCKET NewHandle;
784c2c66affSColin Finck INT Error;
785c2c66affSColin Finck INT OptionLength;
786c2c66affSColin Finck PLIST_ENTRY Entry;
787c2c66affSColin Finck WSAPROTOCOL_INFOW ProtocolInfo;
788c2c66affSColin Finck DWORD UniqueId;
789c2c66affSColin Finck INT ErrorCode;
790c2c66affSColin Finck PTCATALOG_ENTRY CatalogEntry;
791c2c66affSColin Finck
792c2c66affSColin Finck /* Get the catalog lock */
793c2c66affSColin Finck WsTcLock();
794c2c66affSColin Finck
795c2c66affSColin Finck /* Loop as long as the catalog changes */
796c2c66affSColin Finck CatalogChanged:
797c2c66affSColin Finck
798c2c66affSColin Finck /* Loop every provider */
799c2c66affSColin Finck Entry = Catalog->ProtocolList.Flink;
800c2c66affSColin Finck while (Entry != &Catalog->ProtocolList)
801c2c66affSColin Finck {
802c2c66affSColin Finck /* Get the catalog entry */
803c2c66affSColin Finck CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
804c2c66affSColin Finck
805c2c66affSColin Finck /* Move to the next entry */
806c2c66affSColin Finck Entry = Entry->Flink;
807c2c66affSColin Finck
808c2c66affSColin Finck /* Skip it if it doesn't support IFS */
809c2c66affSColin Finck if (!(CatalogEntry->ProtocolInfo.dwServiceFlags1 & XP1_IFS_HANDLES)) continue;
810c2c66affSColin Finck
811c2c66affSColin Finck /* Check if we need to load it */
812c2c66affSColin Finck if (!(Provider = CatalogEntry->Provider))
813c2c66affSColin Finck {
814c2c66affSColin Finck /* Load it */
815c2c66affSColin Finck ErrorCode = WsTcLoadProvider(Catalog, CatalogEntry);
816c2c66affSColin Finck
817c2c66affSColin Finck /* Skip it if we failed to load it */
818c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS) continue;
819c2c66affSColin Finck
820c2c66affSColin Finck /* Get the provider again */
821c2c66affSColin Finck Provider = CatalogEntry->Provider;
822c2c66affSColin Finck }
823c2c66affSColin Finck
824c2c66affSColin Finck /* Reference the entry and get our unique id */
825c2c66affSColin Finck InterlockedIncrement(&CatalogEntry->RefCount);
826c2c66affSColin Finck UniqueId = Catalog->UniqueId;
827c2c66affSColin Finck
828c2c66affSColin Finck /* Release the lock now */
829c2c66affSColin Finck WsTcUnlock();
830c2c66affSColin Finck
831c2c66affSColin Finck /* Get the catalog entry ID */
832c2c66affSColin Finck OptionLength = sizeof(ProtocolInfo);
833c2c66affSColin Finck ErrorCode = Provider->Service.lpWSPGetSockOpt(Handle,
834c2c66affSColin Finck SOL_SOCKET,
835c2c66affSColin Finck SO_PROTOCOL_INFOW,
836c2c66affSColin Finck (PCHAR)&ProtocolInfo,
837c2c66affSColin Finck &OptionLength,
838c2c66affSColin Finck &Error);
839c2c66affSColin Finck
840c2c66affSColin Finck /* Dereference the entry and check the result */
841c2c66affSColin Finck WsTcEntryDereference(CatalogEntry);
842c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS)
843c2c66affSColin Finck {
844c2c66affSColin Finck /* Lock and make sure this provider is still valid */
845c2c66affSColin Finck WsTcLock();
846c2c66affSColin Finck if (UniqueId == Catalog->UniqueId) continue;
847c2c66affSColin Finck
848c2c66affSColin Finck /* It changed! We need to start over */
849c2c66affSColin Finck goto CatalogChanged;
850c2c66affSColin Finck }
851c2c66affSColin Finck
852c2c66affSColin Finck /* Now get the IFS handle */
853c2c66affSColin Finck NewHandle = WPUModifyIFSHandle(ProtocolInfo.dwCatalogEntryId,
854c2c66affSColin Finck Handle,
855c2c66affSColin Finck &Error);
856c2c66affSColin Finck
857c2c66affSColin Finck /* Check if the socket is invalid */
858c2c66affSColin Finck if (NewHandle == INVALID_SOCKET) return WSAENOTSOCK;
859c2c66affSColin Finck
860c2c66affSColin Finck /* We succeeded, get out of here */
861c2c66affSColin Finck return ERROR_SUCCESS;
862c2c66affSColin Finck }
863c2c66affSColin Finck
864c2c66affSColin Finck /* Unrecognized socket if we get here: note, we still have the lock */
865c2c66affSColin Finck WsTcUnlock();
866c2c66affSColin Finck return WSAENOTSOCK;
867c2c66affSColin Finck }
868c2c66affSColin Finck
869c2c66affSColin Finck VOID
870c2c66affSColin Finck WSAAPI
WsTcRemoveCatalogItem(IN PTCATALOG Catalog,IN PTCATALOG_ENTRY Entry)871c2c66affSColin Finck WsTcRemoveCatalogItem(IN PTCATALOG Catalog,
872c2c66affSColin Finck IN PTCATALOG_ENTRY Entry)
873c2c66affSColin Finck {
874c2c66affSColin Finck /* Remove the entry from the list */
875c2c66affSColin Finck RemoveEntryList(&Entry->CatalogLink);
876c2c66affSColin Finck
877c2c66affSColin Finck /* Decrease our count */
878c2c66affSColin Finck Catalog->ItemCount--;
879c2c66affSColin Finck }
880c2c66affSColin Finck
881c2c66affSColin Finck VOID
882c2c66affSColin Finck WSAAPI
WsTcDelete(IN PTCATALOG Catalog)883c2c66affSColin Finck WsTcDelete(IN PTCATALOG Catalog)
884c2c66affSColin Finck {
885c2c66affSColin Finck PLIST_ENTRY Entry;
886c2c66affSColin Finck PTCATALOG_ENTRY CatalogEntry;
887c2c66affSColin Finck
888c2c66affSColin Finck /* Check if we're initialized */
889c2c66affSColin Finck if (!Catalog->ProtocolList.Flink) return;
890c2c66affSColin Finck
891c2c66affSColin Finck /* Acquire lock */
892c2c66affSColin Finck WsTcLock();
893c2c66affSColin Finck
894c2c66affSColin Finck /* Loop every entry */
895c2c66affSColin Finck Entry = Catalog->ProtocolList.Flink;
896c2c66affSColin Finck while (Entry != &Catalog->ProtocolList)
897c2c66affSColin Finck {
898c2c66affSColin Finck /* Get this entry */
899c2c66affSColin Finck CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink);
900c2c66affSColin Finck
901c2c66affSColin Finck /* Remove it and dereference it */
902c2c66affSColin Finck WsTcRemoveCatalogItem(Catalog, CatalogEntry);
903c2c66affSColin Finck WsTcEntryDereference(CatalogEntry);
904c2c66affSColin Finck
905c2c66affSColin Finck /* Move to the next entry */
906c2c66affSColin Finck Entry = Catalog->ProtocolList.Flink;
907c2c66affSColin Finck }
908c2c66affSColin Finck
909c2c66affSColin Finck /* Check if the catalog key is opened */
910c2c66affSColin Finck if (Catalog->CatalogKey)
911c2c66affSColin Finck {
912c2c66affSColin Finck /* Close it */
913c2c66affSColin Finck RegCloseKey(Catalog->CatalogKey);
914c2c66affSColin Finck Catalog->CatalogKey = NULL;
915c2c66affSColin Finck }
916c2c66affSColin Finck
917c2c66affSColin Finck /* Release and delete the lock */
918c2c66affSColin Finck WsTcUnlock();
919c2c66affSColin Finck DeleteCriticalSection(&Catalog->Lock);
920c2c66affSColin Finck
921c2c66affSColin Finck /* Delete the object */
922c2c66affSColin Finck HeapFree(WsSockHeap, 0, Catalog);
923c2c66affSColin Finck }
924