Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendcatalog.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS WinSock 2 API 00004 * FILE: dcatalog.c 00005 * PURPOSE: Transport Catalog Object 00006 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 #include "ws2_32.h" 00011 00012 /* DATA **********************************************************************/ 00013 00014 #define TCCATALOG_NAME "Protocol_Catalog9" 00015 00016 #define WsTcLock() EnterCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock); 00017 #define WsTcUnlock() LeaveCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock); 00018 00019 /* FUNCTIONS *****************************************************************/ 00020 00021 PTCATALOG 00022 WSAAPI 00023 WsTcAllocate(VOID) 00024 { 00025 PTCATALOG Catalog; 00026 00027 /* Allocate the object */ 00028 Catalog = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Catalog)); 00029 00030 /* Return it */ 00031 return Catalog; 00032 } 00033 00034 BOOL 00035 WSAAPI 00036 WsTcOpen(IN PTCATALOG Catalog, 00037 IN HKEY ParentKey) 00038 { 00039 INT ErrorCode; 00040 DWORD CreateDisposition; 00041 HKEY CatalogKey, NewKey; 00042 //DWORD CatalogEntries = 0; 00043 DWORD RegType = REG_DWORD; 00044 DWORD RegSize = sizeof(DWORD); 00045 DWORD UniqueId = 0; 00046 DWORD NewData = 0; 00047 00048 /* Initialize the catalog lock and namespace list */ 00049 InitializeCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock); 00050 InitializeListHead(&Catalog->ProtocolList); 00051 00052 /* Open the Catalog Key */ 00053 ErrorCode = RegOpenKeyEx(ParentKey, 00054 TCCATALOG_NAME, 00055 0, 00056 MAXIMUM_ALLOWED, 00057 &CatalogKey); 00058 00059 /* If we didn't find the key, create it */ 00060 if (ErrorCode == ERROR_SUCCESS) 00061 { 00062 /* Fake that we opened an existing key */ 00063 CreateDisposition = REG_OPENED_EXISTING_KEY; 00064 } 00065 else if (ErrorCode == ERROR_FILE_NOT_FOUND) 00066 { 00067 /* Create the Catalog Name */ 00068 ErrorCode = RegCreateKeyEx(ParentKey, 00069 TCCATALOG_NAME, 00070 0, 00071 NULL, 00072 REG_OPTION_NON_VOLATILE, 00073 KEY_ALL_ACCESS, 00074 NULL, 00075 &CatalogKey, 00076 &CreateDisposition); 00077 } 00078 00079 /* Fail if that didn't work */ 00080 if (ErrorCode != ERROR_SUCCESS) return FALSE; 00081 00082 /* Check if we had to create the key */ 00083 if (CreateDisposition == REG_CREATED_NEW_KEY) 00084 { 00085 /* Write the count of entries (0 now) */ 00086 ErrorCode = RegSetValueEx(CatalogKey, 00087 "Num_Catalog_Entries", 00088 0, 00089 REG_DWORD, 00090 (LPBYTE)&NewData, 00091 sizeof(NewData)); 00092 if (ErrorCode != ERROR_SUCCESS) 00093 { 00094 /* Close the key and fail */ 00095 RegCloseKey(CatalogKey); 00096 return FALSE; 00097 } 00098 00099 /* Write the first catalog entry ID */ 00100 NewData = 1001; 00101 ErrorCode = RegSetValueEx(CatalogKey, 00102 "Next_Catalog_Entry_ID", 00103 0, 00104 REG_DWORD, 00105 (LPBYTE)&NewData, 00106 sizeof(NewData)); 00107 if (ErrorCode != ERROR_SUCCESS) 00108 { 00109 /* Close the key and fail */ 00110 RegCloseKey(CatalogKey); 00111 return FALSE; 00112 } 00113 00114 /* Write the first catalog entry Uniqe ID */ 00115 NewData = 1; 00116 ErrorCode = RegSetValueEx(CatalogKey, 00117 "Serial_Access_Num", 00118 0, 00119 REG_DWORD, 00120 (LPBYTE)&NewData, 00121 sizeof(NewData)); 00122 if (ErrorCode != ERROR_SUCCESS) 00123 { 00124 /* Close the key and fail */ 00125 RegCloseKey(CatalogKey); 00126 return FALSE; 00127 } 00128 00129 /* Create a key for this entry */ 00130 ErrorCode = RegCreateKeyEx(CatalogKey, 00131 "Catalog_Entries", 00132 0, 00133 NULL, 00134 REG_OPTION_NON_VOLATILE, 00135 KEY_ALL_ACCESS, 00136 NULL, 00137 &NewKey, 00138 &CreateDisposition); 00139 if (ErrorCode != ERROR_SUCCESS) 00140 { 00141 /* Close the key and fail */ 00142 RegCloseKey(CatalogKey); 00143 return FALSE; 00144 } 00145 00146 /* Close the key since we don't need it */ 00147 RegCloseKey(NewKey); 00148 } 00149 else 00150 { 00151 /* Read the serial number */ 00152 ErrorCode = RegQueryValueEx(CatalogKey, 00153 "Serial_Access_Num", 00154 0, 00155 &RegType, 00156 (LPBYTE)&UniqueId, 00157 &RegSize); 00158 00159 /* Check if it's missing for some reason */ 00160 if (ErrorCode != ERROR_SUCCESS) 00161 { 00162 /* Write the first catalog entry Unique ID */ 00163 NewData = 1; 00164 ErrorCode = RegSetValueEx(CatalogKey, 00165 "Serial_Access_Num", 00166 0, 00167 REG_DWORD, 00168 (LPBYTE)&NewData, 00169 sizeof(NewData)); 00170 } 00171 } 00172 00173 /* Set the Catalog Key */ 00174 Catalog->CatalogKey = CatalogKey; 00175 return TRUE; 00176 } 00177 00178 DWORD 00179 WSAAPI 00180 WsTcInitializeFromRegistry(IN PTCATALOG Catalog, 00181 IN HKEY ParentKey, 00182 IN HANDLE CatalogEvent) 00183 { 00184 INT ErrorCode = WSASYSCALLFAILURE; 00185 00186 /* Open the catalog */ 00187 if (WsTcOpen(Catalog, ParentKey)) 00188 { 00189 /* Refresh it */ 00190 ErrorCode = WsTcRefreshFromRegistry(Catalog, CatalogEvent); 00191 } 00192 00193 /* Return the status */ 00194 return ErrorCode; 00195 } 00196 00197 DWORD 00198 WSAAPI 00199 WsTcRefreshFromRegistry(IN PTCATALOG Catalog, 00200 IN HANDLE CatalogEvent) 00201 { 00202 INT ErrorCode; 00203 BOOLEAN LocalEvent = FALSE; 00204 LIST_ENTRY LocalList; 00205 DWORD UniqueId; 00206 HKEY EntriesKey; 00207 DWORD CatalogEntries; 00208 PTCATALOG_ENTRY CatalogEntry; 00209 DWORD NextCatalogEntry; 00210 BOOL NewChangesMade; 00211 PLIST_ENTRY Entry; 00212 DWORD RegType = REG_DWORD; 00213 DWORD RegSize = sizeof(DWORD); 00214 DWORD i; 00215 00216 /* Check if we got an event */ 00217 if (!CatalogEvent) 00218 { 00219 /* Create an event ourselves */ 00220 CatalogEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 00221 if (!CatalogEvent) return WSASYSCALLFAILURE; 00222 LocalEvent = TRUE; 00223 } 00224 00225 /* Lock the catalog */ 00226 WsTcLock(); 00227 00228 /* Initialize our local list for the loop */ 00229 InitializeListHead(&LocalList); 00230 00231 /* Start looping */ 00232 do 00233 { 00234 /* Setup notifications for the catalog entry */ 00235 ErrorCode = WsSetupCatalogProtection(Catalog->CatalogKey, 00236 CatalogEvent, 00237 &UniqueId); 00238 if (ErrorCode != ERROR_SUCCESS) break; 00239 00240 /* Check if we've changed till now */ 00241 if (UniqueId == Catalog->UniqueId) 00242 { 00243 /* We haven't, so return */ 00244 ErrorCode = ERROR_SUCCESS; 00245 break; 00246 } 00247 00248 /* Now Open the Entries */ 00249 ErrorCode = RegOpenKeyEx(Catalog->CatalogKey, 00250 "Catalog_Entries", 00251 0, 00252 MAXIMUM_ALLOWED, 00253 &EntriesKey); 00254 if (ErrorCode != ERROR_SUCCESS) 00255 { 00256 /* Critical failure */ 00257 ErrorCode = WSASYSCALLFAILURE; 00258 break; 00259 } 00260 00261 /* Get the next entry */ 00262 ErrorCode = RegQueryValueEx(Catalog->CatalogKey, 00263 "Next_Catalog_Entry_ID", 00264 0, 00265 &RegType, 00266 (LPBYTE)&NextCatalogEntry, 00267 &RegSize); 00268 if (ErrorCode != ERROR_SUCCESS) 00269 { 00270 /* Critical failure */ 00271 ErrorCode = WSASYSCALLFAILURE; 00272 break; 00273 } 00274 00275 /* Find out how many there are */ 00276 ErrorCode = RegQueryValueEx(Catalog->CatalogKey, 00277 "Num_Catalog_Entries", 00278 0, 00279 &RegType, 00280 (LPBYTE)&CatalogEntries, 00281 &RegSize); 00282 if (ErrorCode != ERROR_SUCCESS) 00283 { 00284 /* Critical failure */ 00285 ErrorCode = WSASYSCALLFAILURE; 00286 break; 00287 } 00288 00289 /* Initialize them all */ 00290 for (i = 1; i <= CatalogEntries; i++) 00291 { 00292 /* Allocate a Catalog Entry Structure */ 00293 CatalogEntry = WsTcEntryAllocate(); 00294 if (!CatalogEntry) 00295 { 00296 /* Not enough memory, fail */ 00297 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 00298 break; 00299 } 00300 00301 /* Initialize it from the Registry Key */ 00302 ErrorCode = WsTcEntryInitializeFromRegistry(CatalogEntry, 00303 EntriesKey, 00304 i); 00305 if (ErrorCode != ERROR_SUCCESS) 00306 { 00307 /* We failed to get it, dereference the entry and leave */ 00308 WsTcEntryDereference(CatalogEntry); 00309 break; 00310 } 00311 00312 /* Insert it to our List */ 00313 InsertTailList(&LocalList, &CatalogEntry->CatalogLink); 00314 } 00315 00316 /* Close the catalog key */ 00317 RegCloseKey(EntriesKey); 00318 00319 /* Check if we changed during our read and if we have success */ 00320 NewChangesMade = WsCheckCatalogState(CatalogEvent); 00321 if (!NewChangesMade && ErrorCode == ERROR_SUCCESS) 00322 { 00323 /* All is good, update the protocol list */ 00324 WsTcUpdateProtocolList(Catalog, &LocalList); 00325 00326 /* Update and return */ 00327 Catalog->UniqueId = UniqueId; 00328 Catalog->NextId = NextCatalogEntry; 00329 break; 00330 } 00331 00332 /* We failed and/or catalog data changed, free what we did till now */ 00333 while (!IsListEmpty(&LocalList)) 00334 { 00335 /* Get the LP Catalog Item */ 00336 Entry = RemoveHeadList(&LocalList); 00337 CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink); 00338 00339 /* Dereference it */ 00340 WsTcEntryDereference(CatalogEntry); 00341 } 00342 } while (NewChangesMade); 00343 00344 /* Release the lock */ 00345 WsTcUnlock(); 00346 00347 /* Close the event, if any was created by us */ 00348 if (LocalEvent) CloseHandle(CatalogEvent); 00349 00350 /* All Done */ 00351 return ErrorCode; 00352 } 00353 00354 DWORD 00355 WSAAPI 00356 WsTcGetEntryFromAf(IN PTCATALOG Catalog, 00357 IN INT AddressFamily, 00358 IN PTCATALOG_ENTRY *CatalogEntry) 00359 { 00360 INT ErrorCode = WSAEINVAL; 00361 PLIST_ENTRY NextEntry = Catalog->ProtocolList.Flink; 00362 PTCATALOG_ENTRY Entry; 00363 00364 /* Assume failure */ 00365 *CatalogEntry = NULL; 00366 00367 /* Lock the catalog */ 00368 WsTcLock(); 00369 00370 /* Match the Id with all the entries in the List */ 00371 while (NextEntry != &Catalog->ProtocolList) 00372 { 00373 /* Get the Current Entry */ 00374 Entry = CONTAINING_RECORD(NextEntry, TCATALOG_ENTRY, CatalogLink); 00375 NextEntry = NextEntry->Flink; 00376 00377 /* Check if this is the Catalog Entry ID we want */ 00378 if (Entry->ProtocolInfo.iAddressFamily == AddressFamily) 00379 { 00380 /* Check if it doesn't already have a provider */ 00381 if (!Entry->Provider) 00382 { 00383 /* Match, load the Provider */ 00384 ErrorCode = WsTcLoadProvider(Catalog, Entry); 00385 00386 /* Make sure this didn't fail */ 00387 if (ErrorCode != ERROR_SUCCESS) break; 00388 } 00389 00390 /* Reference the entry and return it */ 00391 InterlockedIncrement(&Entry->RefCount); 00392 *CatalogEntry = Entry; 00393 ErrorCode = ERROR_SUCCESS; 00394 break; 00395 } 00396 } 00397 00398 /* Release the catalog */ 00399 WsTcUnlock(); 00400 00401 /* Return */ 00402 return ErrorCode; 00403 } 00404 00405 DWORD 00406 WSAAPI 00407 WsTcGetEntryFromCatalogEntryId(IN PTCATALOG Catalog, 00408 IN DWORD CatalogEntryId, 00409 IN PTCATALOG_ENTRY *CatalogEntry) 00410 { 00411 PLIST_ENTRY NextEntry = Catalog->ProtocolList.Flink; 00412 PTCATALOG_ENTRY Entry; 00413 00414 /* Lock the catalog */ 00415 WsTcLock(); 00416 00417 /* Match the Id with all the entries in the List */ 00418 while (NextEntry != &Catalog->ProtocolList) 00419 { 00420 /* Get the Current Entry */ 00421 Entry = CONTAINING_RECORD(NextEntry, TCATALOG_ENTRY, CatalogLink); 00422 NextEntry = NextEntry->Flink; 00423 00424 /* Check if this is the Catalog Entry ID we want */ 00425 if (Entry->ProtocolInfo.dwCatalogEntryId == CatalogEntryId) 00426 { 00427 /* Check if it doesn't already have a provider */ 00428 if (!Entry->Provider) 00429 { 00430 /* Match, load the Provider */ 00431 WsTcLoadProvider(Catalog, Entry); 00432 } 00433 00434 /* Reference the entry and return it */ 00435 InterlockedIncrement(&Entry->RefCount); 00436 *CatalogEntry = Entry; 00437 break; 00438 } 00439 } 00440 00441 /* Release the catalog */ 00442 WsTcUnlock(); 00443 00444 /* Return */ 00445 return ERROR_SUCCESS; 00446 } 00447 00448 DWORD 00449 WSAAPI 00450 WsTcGetEntryFromTriplet(IN PTCATALOG Catalog, 00451 IN INT af, 00452 IN INT type, 00453 IN INT protocol, 00454 IN DWORD StartId, 00455 IN PTCATALOG_ENTRY *CatalogEntry) 00456 { 00457 INT ErrorCode = WSAEINVAL; 00458 PLIST_ENTRY NextEntry = Catalog->ProtocolList.Flink; 00459 PTCATALOG_ENTRY Entry; 00460 00461 /* Assume failure */ 00462 *CatalogEntry = NULL; 00463 00464 /* Lock the catalog */ 00465 WsTcLock(); 00466 00467 /* Check if we are starting past 0 */ 00468 if (StartId) 00469 { 00470 /* Loop the list */ 00471 while (NextEntry != &Catalog->ProtocolList) 00472 { 00473 /* Get the Current Entry */ 00474 Entry = CONTAINING_RECORD(NextEntry, TCATALOG_ENTRY, CatalogLink); 00475 NextEntry = NextEntry->Flink; 00476 00477 /* Check if this is the ID where we are starting */ 00478 if (Entry->ProtocolInfo.dwCatalogEntryId == StartId) break; 00479 } 00480 } 00481 00482 /* Match the Id with all the entries in the List */ 00483 while (NextEntry != &Catalog->ProtocolList) 00484 { 00485 /* Get the Current Entry */ 00486 Entry = CONTAINING_RECORD(NextEntry, TCATALOG_ENTRY, CatalogLink); 00487 NextEntry = NextEntry->Flink; 00488 00489 /* Check if Address Family Matches or if it's wildcard */ 00490 if ((Entry->ProtocolInfo.iAddressFamily == af) || (af == AF_UNSPEC)) 00491 { 00492 /* Check if Socket Type Matches or if it's wildcard */ 00493 if ((Entry->ProtocolInfo.iSocketType == type) || (type == 0)) 00494 { 00495 /* Check if Protocol is In Range or if it's wildcard */ 00496 if (((Entry->ProtocolInfo.iProtocol >= protocol) && 00497 ((Entry->ProtocolInfo.iProtocol + 00498 Entry->ProtocolInfo.iProtocolMaxOffset) <= protocol)) || 00499 (protocol == 0)) 00500 { 00501 /* Check if it doesn't already have a provider */ 00502 if (!Entry->Provider) 00503 { 00504 /* Match, load the Provider */ 00505 ErrorCode = WsTcLoadProvider(Catalog, Entry); 00506 00507 /* Make sure this didn't fail */ 00508 if (ErrorCode != ERROR_SUCCESS) break; 00509 } 00510 00511 /* Reference the entry and return it */ 00512 InterlockedIncrement(&Entry->RefCount); 00513 *CatalogEntry = Entry; 00514 ErrorCode = ERROR_SUCCESS; 00515 break; 00516 } 00517 else 00518 { 00519 ErrorCode = WSAEPROTONOSUPPORT; 00520 } 00521 } 00522 else 00523 { 00524 ErrorCode = WSAESOCKTNOSUPPORT; 00525 } 00526 } 00527 else 00528 { 00529 ErrorCode = WSAEAFNOSUPPORT; 00530 } 00531 } 00532 00533 /* Release the catalog */ 00534 WsTcUnlock(); 00535 00536 /* Return */ 00537 return ErrorCode; 00538 } 00539 00540 PTPROVIDER 00541 WSAAPI 00542 WsTcFindProvider(IN PTCATALOG Catalog, 00543 IN LPGUID ProviderId) 00544 { 00545 PTPROVIDER Provider; 00546 PLIST_ENTRY Entry; 00547 PTCATALOG_ENTRY CatalogEntry; 00548 00549 /* Loop the provider list */ 00550 Entry = Catalog->ProtocolList.Flink; 00551 while (Entry != &Catalog->ProtocolList) 00552 { 00553 /* Get the entry */ 00554 CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink); 00555 00556 /* Move to the next one, get the provider */ 00557 Entry = Entry->Flink; 00558 Provider = CatalogEntry->Provider; 00559 00560 /* Check for a match */ 00561 if ((Provider) && 00562 !(memcmp(&CatalogEntry->ProtocolInfo.ProviderId, 00563 ProviderId, 00564 sizeof(GUID)))) 00565 { 00566 /* Found a match */ 00567 return Provider; 00568 } 00569 } 00570 00571 /* No match here */ 00572 return NULL; 00573 } 00574 00575 DWORD 00576 WSAAPI 00577 WsTcLoadProvider(IN PTCATALOG Catalog, 00578 IN PTCATALOG_ENTRY CatalogEntry) 00579 { 00580 INT ErrorCode = ERROR_SUCCESS; 00581 PTPROVIDER Provider; 00582 00583 /* Lock the catalog */ 00584 WsTcLock(); 00585 00586 /* Check if we have a provider already */ 00587 if (!CatalogEntry->Provider) 00588 { 00589 /* Try to find another instance */ 00590 Provider = WsTcFindProvider(Catalog, 00591 &CatalogEntry->ProtocolInfo.ProviderId); 00592 00593 /* Check if we found one now */ 00594 if (Provider) 00595 { 00596 /* Set this one as the provider */ 00597 WsTcEntrySetProvider(CatalogEntry, Provider); 00598 ErrorCode = ERROR_SUCCESS; 00599 } 00600 else 00601 { 00602 /* Nothing found, Allocate a provider */ 00603 if ((Provider = WsTpAllocate())) 00604 { 00605 /* Initialize it */ 00606 ErrorCode = WsTpInitialize(Provider, 00607 CatalogEntry->DllPath, 00608 &CatalogEntry->ProtocolInfo); 00609 00610 /* Ensure success */ 00611 if (ErrorCode == ERROR_SUCCESS) 00612 { 00613 /* Set the provider */ 00614 WsTcEntrySetProvider(CatalogEntry, Provider); 00615 } 00616 00617 /* Dereference it */ 00618 WsTpDereference(Provider); 00619 } 00620 else 00621 { 00622 /* No memory */ 00623 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 00624 } 00625 } 00626 } 00627 00628 /* Release the lock */ 00629 WsTcUnlock(); 00630 return ErrorCode; 00631 } 00632 00633 VOID 00634 WSAAPI 00635 WsTcUpdateProtocolList(IN PTCATALOG Catalog, 00636 IN PLIST_ENTRY List) 00637 { 00638 LIST_ENTRY TempList; 00639 PTCATALOG_ENTRY CatalogEntry, OldCatalogEntry; 00640 PLIST_ENTRY Entry; 00641 00642 /* First move from our list to the old one */ 00643 InsertHeadList(&Catalog->ProtocolList, &TempList); 00644 RemoveEntryList(&Catalog->ProtocolList); 00645 InitializeListHead(&Catalog->ProtocolList); 00646 00647 /* Loop every item on the list */ 00648 while (!IsListEmpty(List)) 00649 { 00650 /* Get the catalog entry */ 00651 Entry = RemoveHeadList(List); 00652 CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink); 00653 00654 /* Check if this item is already on our list */ 00655 Entry = TempList.Flink; 00656 while (Entry != &TempList) 00657 { 00658 /* Get the catalog entry */ 00659 OldCatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink); 00660 Entry = Entry->Flink; 00661 00662 /* Check if they match */ 00663 if (CatalogEntry->ProtocolInfo.dwCatalogEntryId == 00664 OldCatalogEntry->ProtocolInfo.dwCatalogEntryId) 00665 { 00666 /* We have a match, use the old item instead */ 00667 WsTcEntryDereference(CatalogEntry); 00668 CatalogEntry = OldCatalogEntry; 00669 RemoveEntryList(&CatalogEntry->CatalogLink); 00670 00671 /* Decrease the number of protocols we have */ 00672 Catalog->ItemCount--; 00673 break; 00674 } 00675 } 00676 00677 /* Add this item */ 00678 InsertTailList(&Catalog->ProtocolList, &CatalogEntry->CatalogLink); 00679 Catalog->ItemCount++; 00680 } 00681 00682 /* If there's anything left on the temporary list */ 00683 while (!IsListEmpty(&TempList)) 00684 { 00685 /* Get the entry */ 00686 Entry = RemoveHeadList(&TempList); 00687 CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink); 00688 00689 /* Remove it */ 00690 Catalog->ItemCount--; 00691 WsTcEntryDereference(CatalogEntry); 00692 } 00693 } 00694 00695 VOID 00696 WSAAPI 00697 WsTcEnumerateCatalogItems(IN PTCATALOG Catalog, 00698 IN PTCATALOG_ENUMERATE_PROC Callback, 00699 IN PVOID Context) 00700 { 00701 PLIST_ENTRY Entry; 00702 PTCATALOG_ENTRY CatalogEntry; 00703 BOOL GoOn = TRUE; 00704 00705 /* Lock the catalog */ 00706 WsTcLock(); 00707 00708 /* Loop the entries */ 00709 Entry = Catalog->ProtocolList.Flink; 00710 while (GoOn && (Entry != &Catalog->ProtocolList)) 00711 { 00712 /* Get the entry */ 00713 CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink); 00714 00715 /* Move to the next one and call the callback */ 00716 Entry = Entry->Flink; 00717 GoOn = Callback(Context, CatalogEntry); 00718 } 00719 00720 /* Release lock */ 00721 WsTcUnlock(); 00722 } 00723 00724 DWORD 00725 WSAAPI 00726 WsTcFindIfsProviderForSocket(IN PTCATALOG Catalog, 00727 IN SOCKET Handle) 00728 { 00729 PTPROVIDER Provider; 00730 IN SOCKET NewHandle; 00731 INT Error; 00732 DWORD OptionLength; 00733 PLIST_ENTRY Entry; 00734 WSAPROTOCOL_INFOW ProtocolInfo; 00735 DWORD UniqueId; 00736 INT ErrorCode; 00737 PTCATALOG_ENTRY CatalogEntry; 00738 00739 /* Get the catalog lock */ 00740 WsTcLock(); 00741 00742 /* Loop as long as the catalog changes */ 00743 CatalogChanged: 00744 00745 /* Loop every provider */ 00746 Entry = Catalog->ProtocolList.Flink; 00747 while (Entry != &Catalog->ProtocolList) 00748 { 00749 /* Get the catalog entry */ 00750 CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink); 00751 00752 /* Move to the next entry */ 00753 Entry = Entry->Flink; 00754 00755 /* Skip it if it doesn't support IFS */ 00756 if (!(CatalogEntry->ProtocolInfo.dwServiceFlags1 & XP1_IFS_HANDLES)) continue; 00757 00758 /* Check if we need to load it */ 00759 if (!(Provider = CatalogEntry->Provider)) 00760 { 00761 /* Load it */ 00762 ErrorCode = WsTcLoadProvider(Catalog, CatalogEntry); 00763 00764 /* Skip it if we failed to load it */ 00765 if (ErrorCode != ERROR_SUCCESS) continue; 00766 00767 /* Get the provider again */ 00768 Provider = CatalogEntry->Provider; 00769 } 00770 00771 /* Reference the entry and get our unique id */ 00772 InterlockedIncrement(&CatalogEntry->RefCount); 00773 UniqueId = Catalog->UniqueId; 00774 00775 /* Release the lock now */ 00776 WsTcUnlock(); 00777 00778 /* Get the catalog entry ID */ 00779 OptionLength = sizeof(ProtocolInfo); 00780 ErrorCode = Provider->Service.lpWSPGetSockOpt(Handle, 00781 SOL_SOCKET, 00782 SO_PROTOCOL_INFOW, 00783 (PCHAR)&ProtocolInfo, 00784 (LPINT)&OptionLength, 00785 &Error); 00786 00787 /* Dereference the entry and check the result */ 00788 WsTcEntryDereference(CatalogEntry); 00789 if (ErrorCode != ERROR_SUCCESS) 00790 { 00791 /* Lock and make sure this provider is still valid */ 00792 WsTcLock(); 00793 if (UniqueId == Catalog->UniqueId) continue; 00794 00795 /* It changed! We need to start over */ 00796 goto CatalogChanged; 00797 } 00798 00799 /* Now get the IFS handle */ 00800 NewHandle = WPUModifyIFSHandle(ProtocolInfo.dwCatalogEntryId, 00801 Handle, 00802 &Error); 00803 00804 /* Check if the socket is invalid */ 00805 if (NewHandle == INVALID_SOCKET) return WSAENOTSOCK; 00806 00807 /* We suceeded, get out of here */ 00808 return ERROR_SUCCESS; 00809 } 00810 00811 /* Unrecognized socket if we get here: note, we still have the lock */ 00812 WsTcUnlock(); 00813 return WSAENOTSOCK; 00814 } 00815 00816 VOID 00817 WSAAPI 00818 WsTcRemoveCatalogItem(IN PTCATALOG Catalog, 00819 IN PTCATALOG_ENTRY Entry) 00820 { 00821 /* Remove the entry from the list */ 00822 RemoveEntryList(&Entry->CatalogLink); 00823 00824 /* Decrease our count */ 00825 Catalog->ItemCount--; 00826 } 00827 00828 VOID 00829 WSAAPI 00830 WsTcDelete(IN PTCATALOG Catalog) 00831 { 00832 PLIST_ENTRY Entry; 00833 PTCATALOG_ENTRY CatalogEntry; 00834 00835 /* Check if we're initialized */ 00836 if (!Catalog->ProtocolList.Flink) return; 00837 00838 /* Acquire lock */ 00839 WsTcLock(); 00840 00841 /* Loop every entry */ 00842 Entry = Catalog->ProtocolList.Flink; 00843 while (Entry != &Catalog->ProtocolList) 00844 { 00845 /* Get this entry */ 00846 CatalogEntry = CONTAINING_RECORD(Entry, TCATALOG_ENTRY, CatalogLink); 00847 00848 /* Remove it */ 00849 WsTcRemoveCatalogItem(Catalog, CatalogEntry); 00850 00851 /* Dereference it */ 00852 WsTcEntryDereference(CatalogEntry); 00853 00854 /* Move to the next entry */ 00855 Entry = Catalog->ProtocolList.Flink; 00856 } 00857 00858 /* Check if the catalog key is opened */ 00859 if (Catalog->CatalogKey) 00860 { 00861 /* Close it */ 00862 RegCloseKey(Catalog->CatalogKey); 00863 Catalog->CatalogKey = NULL; 00864 } 00865 00866 /* Release and delete the lock */ 00867 WsTcUnlock(); 00868 DeleteCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock); 00869 00870 /* Delete the object */ 00871 HeapFree(WsSockHeap, 0, Catalog); 00872 } Generated on Sun May 27 2012 04:27:09 for ReactOS by
1.7.6.1
|