ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dcatalog.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.