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

nscatalo.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:        nscatalo.c
00005  * PURPOSE:     Namespace Catalog Object
00006  * PROGRAMMER:  Alex Ionescu (alex@relsoft.net)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 #include "ws2_32.h"
00011 
00012 /* DATA **********************************************************************/
00013 
00014 #define NSCATALOG_NAME      "NameSpace_Catalog5"
00015 #define WsNcLock()          EnterCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock);
00016 #define WsNcUnlock()        LeaveCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock);
00017 
00018 /* FUNCTIONS *****************************************************************/
00019 
00020 PNSCATALOG
00021 WSAAPI
00022 WsNcAllocate(VOID)
00023 {
00024     PNSCATALOG Catalog;
00025 
00026     /* Allocate the catalog */
00027     Catalog = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Catalog));
00028 
00029     /* Return it */
00030     return Catalog;
00031 }
00032 
00033 BOOLEAN
00034 WSAAPI
00035 WsNcOpen(IN PNSCATALOG Catalog,
00036          IN HKEY ParentKey)
00037 {
00038     LONG ErrorCode;
00039     DWORD CreateDisposition;
00040     HKEY CatalogKey, NewKey;
00041     //DWORD CatalogEntries = 0;
00042     DWORD RegType = REG_DWORD;
00043     DWORD RegSize = sizeof(DWORD);
00044     DWORD UniqueId = 0;
00045     DWORD NewData = 0;
00046 
00047     /* Initialize the catalog lock and namespace list */
00048     InitializeCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock);
00049     InitializeListHead(&Catalog->CatalogList);
00050 
00051     /* Open the Catalog Key */
00052     ErrorCode = RegOpenKeyEx(ParentKey,
00053                              NSCATALOG_NAME,
00054                              0,
00055                              MAXIMUM_ALLOWED,
00056                              &CatalogKey);
00057 
00058     /* If we didn't find the key, create it */
00059     if (ErrorCode == ERROR_SUCCESS)
00060     {
00061         /* Fake that we opened an existing key */
00062         CreateDisposition = REG_OPENED_EXISTING_KEY;
00063     }
00064     else if (ErrorCode == ERROR_FILE_NOT_FOUND)
00065     {
00066         /* Create the Catalog Name */
00067         ErrorCode = RegCreateKeyEx(ParentKey,
00068                                    NSCATALOG_NAME,
00069                                    0,
00070                                    NULL,
00071                                    REG_OPTION_NON_VOLATILE,
00072                                    KEY_ALL_ACCESS,
00073                                    NULL,
00074                                    &CatalogKey,
00075                                    &CreateDisposition);
00076     }
00077 
00078     /* Fail if that didn't work */
00079     if (ErrorCode != ERROR_SUCCESS) return FALSE;
00080 
00081     /* Check if we had to create the key */
00082     if (CreateDisposition == REG_CREATED_NEW_KEY)
00083     {
00084         /* Write the count of entries (0 now) */
00085         ErrorCode = RegSetValueEx(CatalogKey,
00086                                   "Num_Catalog_Entries",
00087                                   0,
00088                                   REG_DWORD,
00089                                   (LPBYTE)&NewData,
00090                                   sizeof(NewData));
00091         if (ErrorCode != ERROR_SUCCESS)
00092         {
00093             /* Close the key and fail */
00094             RegCloseKey(CatalogKey);
00095             return FALSE;
00096         }
00097 
00098         /* Write the first catalog entry Uniqe ID */
00099         NewData = 1;
00100         ErrorCode = RegSetValueEx(CatalogKey,
00101                                   "Serial_Access_Num",
00102                                   0,
00103                                   REG_DWORD,
00104                                   (LPBYTE)&NewData,
00105                                   sizeof(NewData));
00106         if (ErrorCode != ERROR_SUCCESS)
00107         {
00108             /* Close the key and fail */
00109             RegCloseKey(CatalogKey);
00110             return FALSE;
00111         }
00112 
00113         /* Create a key for this entry */
00114         ErrorCode = RegCreateKeyEx(CatalogKey,
00115                                    "Catalog_Entries",
00116                                    0,
00117                                    NULL,
00118                                    REG_OPTION_NON_VOLATILE,
00119                                    KEY_ALL_ACCESS,
00120                                    NULL,
00121                                    &NewKey,
00122                                    &CreateDisposition);
00123         if (ErrorCode != ERROR_SUCCESS)
00124         {
00125             /* Close the key and fail */
00126             RegCloseKey(CatalogKey);
00127             return FALSE;
00128         }
00129 
00130         /* Close the key since we don't need it */
00131         RegCloseKey(NewKey);
00132     }
00133     else
00134     {
00135         /* Read the serial number */
00136         ErrorCode = RegQueryValueEx(CatalogKey,
00137                                     "Serial_Access_Num",
00138                                     0,
00139                                     &RegType,
00140                                     (LPBYTE)&UniqueId,
00141                                     &RegSize);
00142 
00143         /* Check if it's missing for some reason */
00144         if (ErrorCode != ERROR_SUCCESS)
00145         {
00146             /* Write the first catalog entry Unique ID */
00147             NewData = 1;
00148             ErrorCode = RegSetValueEx(CatalogKey,
00149                                       "Serial_Access_Num",
00150                                       0,
00151                                       REG_DWORD,
00152                                       (LPBYTE)&NewData,
00153                                       sizeof(NewData));
00154         }
00155     }
00156 
00157     /* Set the Catalog Key */
00158     Catalog->CatalogKey = CatalogKey;
00159     return TRUE;
00160 }
00161 
00162 INT
00163 WSAAPI
00164 WsNcInitializeFromRegistry(IN PNSCATALOG Catalog,
00165                            IN HKEY ParentKey,
00166                            IN HANDLE CatalogEvent)
00167 {
00168     INT ErrorCode = WSASYSCALLFAILURE;
00169 
00170     /* Open the catalog */
00171     if (WsNcOpen(Catalog, ParentKey))
00172     {
00173         /* Refresh it */
00174         ErrorCode = WsNcRefreshFromRegistry(Catalog, CatalogEvent);
00175     }
00176 
00177     /* Return the status */
00178     return ErrorCode;
00179 }
00180 
00181 INT
00182 WSAAPI
00183 WsNcRefreshFromRegistry(IN PNSCATALOG Catalog,
00184                         IN HANDLE CatalogEvent)
00185 {
00186     INT ErrorCode;
00187     BOOLEAN LocalEvent = FALSE;
00188     LIST_ENTRY LocalList;
00189     DWORD UniqueId;
00190     HKEY EntriesKey;
00191     DWORD CatalogEntries;
00192     PNSCATALOG_ENTRY CatalogEntry;
00193     BOOL NewChangesMade;
00194     PLIST_ENTRY Entry;
00195     DWORD RegType = REG_DWORD;
00196     DWORD RegSize = sizeof(DWORD);
00197     DWORD i;
00198 
00199     /* Check if we got an event */
00200     if (!CatalogEvent)
00201     {
00202         /* Create an event ourselves */
00203         CatalogEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00204         if (!CatalogEvent) return WSASYSCALLFAILURE;
00205         LocalEvent = TRUE;
00206     }
00207 
00208     /* Lock the catalog */
00209     WsNcLock();
00210 
00211     /* Initialize our local list for the loop */
00212     InitializeListHead(&LocalList);
00213 
00214     /* Start looping */
00215     do
00216     {
00217         /* Setup notifications for the catalog entry */
00218         ErrorCode = WsSetupCatalogProtection(Catalog->CatalogKey,
00219                                              CatalogEvent,
00220                                              &UniqueId);
00221         if (ErrorCode != ERROR_SUCCESS) break;
00222 
00223         /* Check if we've changed till now */
00224         if (UniqueId == Catalog->UniqueId)
00225         {
00226             /* We haven't, so return */
00227             ErrorCode = ERROR_SUCCESS;
00228             break;
00229         }
00230 
00231         /* Now Open the Entries */
00232         ErrorCode = RegOpenKeyEx(Catalog->CatalogKey,
00233                                  "Catalog_Entries",
00234                                  0,
00235                                  MAXIMUM_ALLOWED,
00236                                  &EntriesKey);
00237         if (ErrorCode != ERROR_SUCCESS)
00238         {
00239             /* Critical failure */
00240             ErrorCode = WSASYSCALLFAILURE;
00241             break;
00242         }
00243 
00244         /* Find out how many there are */
00245         ErrorCode = RegQueryValueEx(Catalog->CatalogKey,
00246                                     "Num_Catalog_Entries",
00247                                     0,
00248                                     &RegType,
00249                                     (LPBYTE)&CatalogEntries,
00250                                     &RegSize);
00251         if (ErrorCode != ERROR_SUCCESS)
00252         {
00253             /* Critical failure */
00254             ErrorCode = WSASYSCALLFAILURE;
00255             break;
00256         }
00257 
00258         /* Initialize them all */
00259         for (i = 1; i <= CatalogEntries; i++) 
00260         {
00261             /* Allocate a Catalog Entry Structure */
00262             CatalogEntry = WsNcEntryAllocate();
00263             if (!CatalogEntry)
00264             {
00265                 /* Not enough memory, fail */
00266                 ErrorCode = WSA_NOT_ENOUGH_MEMORY;
00267                 break;
00268             }
00269 
00270             /* Initialize it from the Registry Key */
00271             ErrorCode = WsNcEntryInitializeFromRegistry(CatalogEntry,
00272                                                         EntriesKey,
00273                                                         i);
00274             if (ErrorCode != ERROR_SUCCESS)
00275             {
00276                 /* We failed to get it, dereference the entry and leave */
00277                 WsNcEntryDereference(CatalogEntry);
00278                 break;
00279             }
00280 
00281             /* Insert it to our List */
00282             InsertTailList(&LocalList, &CatalogEntry->CatalogLink);
00283         }
00284 
00285         /* Close the catalog key */
00286         RegCloseKey(EntriesKey);
00287 
00288         /* Check if we changed during our read and if we have success */
00289         NewChangesMade = WsCheckCatalogState(CatalogEvent);
00290         if (!NewChangesMade && ErrorCode == ERROR_SUCCESS)
00291         {
00292             /* All is good, update the protocol list */
00293             WsNcUpdateNamespaceList(Catalog, &LocalList);
00294 
00295             /* Update and return */
00296             Catalog->UniqueId = UniqueId;
00297             break;
00298         }
00299 
00300         /* We failed and/or catalog data changed, free what we did till now */
00301         while (!IsListEmpty(&LocalList))
00302         {
00303             /* Get the LP Catalog Item */
00304             Entry = RemoveHeadList(&LocalList);
00305             CatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink);
00306 
00307             /* Dereference it */
00308             WsNcEntryDereference(CatalogEntry);
00309         }
00310     } while (NewChangesMade);
00311 
00312     /* Release the lock */
00313     WsNcUnlock();
00314 
00315     /* Close the event, if any was created by us */
00316     if (LocalEvent) CloseHandle(CatalogEvent);
00317 
00318     /* All Done */
00319     return ErrorCode;
00320 }
00321 
00322 VOID
00323 WSAAPI
00324 WsNcEnumerateCatalogItems(IN PNSCATALOG Catalog,
00325                           IN PNSCATALOG_ENUMERATE_PROC Callback,
00326                           IN PVOID Context)
00327 {
00328     PLIST_ENTRY Entry;
00329     PNSCATALOG_ENTRY CatalogEntry;
00330     BOOL GoOn = TRUE;
00331 
00332     /* Lock the catalog */
00333     WsNcLock();
00334 
00335     /* Loop the entries */
00336     Entry = Catalog->CatalogList.Flink;
00337     while (GoOn && (Entry != &Catalog->CatalogList))
00338     {
00339         /* Get the entry */
00340         CatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink);
00341 
00342         /* Move to the next one and call the callback */
00343         Entry = Entry->Flink;
00344         GoOn = Callback(Context, CatalogEntry);
00345     }
00346 
00347     /* Release lock */
00348     WsNcUnlock();
00349 }
00350 
00351 INT
00352 WSAAPI
00353 WsNcLoadProvider(IN PNSCATALOG Catalog,
00354                  IN PNSCATALOG_ENTRY CatalogEntry)
00355 {
00356     INT ErrorCode = ERROR_SUCCESS;
00357     PNS_PROVIDER Provider;
00358 
00359     /* Lock the catalog */
00360     WsNcLock();
00361 
00362     /* Check if we have a provider already */
00363     if (!CatalogEntry->Provider)
00364     {
00365         /* Allocate a provider */
00366         if ((Provider = WsNpAllocate()))
00367         {
00368             /* Initialize it */
00369             ErrorCode = WsNpInitialize(Provider,
00370                                        CatalogEntry->DllPath,
00371                                        &CatalogEntry->ProviderId);
00372 
00373                 /* Ensure success */
00374                 if (ErrorCode == ERROR_SUCCESS)
00375                 {
00376                     /* Set the provider */
00377                     WsNcEntrySetProvider(CatalogEntry, Provider);
00378                 }
00379 
00380             /* Dereference it */
00381             WsNpDereference(Provider);
00382         }
00383         else
00384         {
00385             /* No memory */
00386             ErrorCode = WSA_NOT_ENOUGH_MEMORY;
00387         }
00388     }
00389 
00390     /* Release the lock */
00391     WsNcUnlock();
00392     return ErrorCode;
00393 }
00394 
00395 INT
00396 WSAAPI
00397 WsNcGetServiceClassInfo(IN PNSCATALOG Catalog,
00398                         IN OUT LPDWORD BugSize,
00399                         IN OUT LPWSASERVICECLASSINFOW lpServiceClassInfo)
00400 {
00401     /* Not yet implemented in the spec? */
00402     SetLastError(ERROR_SUCCESS);
00403     return SOCKET_ERROR;
00404 }
00405 
00406 VOID
00407 WSAAPI
00408 WsNcUpdateNamespaceList(IN PNSCATALOG Catalog,
00409                         IN PLIST_ENTRY List)
00410 {
00411     LIST_ENTRY TempList;
00412     PNSCATALOG_ENTRY CatalogEntry, OldCatalogEntry;
00413     PLIST_ENTRY Entry;
00414 
00415     /* First move from our list to the old one */
00416     InsertHeadList(&Catalog->CatalogList, &TempList);
00417     RemoveEntryList(&Catalog->CatalogList);
00418     InitializeListHead(&Catalog->CatalogList);
00419 
00420     /* Loop every item on the list */
00421     while (!IsListEmpty(List))
00422     {
00423         /* Get the catalog entry */
00424         Entry = RemoveHeadList(List);
00425         CatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink);
00426 
00427         /* Check if this item is already on our list */
00428         Entry = TempList.Flink;
00429         while (Entry != &TempList)
00430         {
00431             /* Get the catalog entry */
00432             OldCatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink);
00433             Entry = Entry->Flink;
00434 
00435             /* Check if they match */
00436             if (memcmp(&CatalogEntry->ProviderId,
00437                        &OldCatalogEntry->ProviderId,
00438                        sizeof(GUID)))
00439             {
00440                 /* We have a match, use the old item instead */
00441                 WsNcEntryDereference(CatalogEntry);
00442                 CatalogEntry = OldCatalogEntry;
00443                 RemoveEntryList(&CatalogEntry->CatalogLink);
00444 
00445                 /* Decrease the number of protocols we have */
00446                 Catalog->ItemCount--;
00447                 break;
00448             }
00449         }
00450 
00451         /* Add this item */
00452         InsertTailList(&Catalog->CatalogList, &CatalogEntry->CatalogLink);
00453         Catalog->ItemCount++;
00454     }
00455 
00456     /* If there's anything left on the temporary list */
00457     while (!IsListEmpty(&TempList))
00458     {
00459         /* Get the entry */
00460         Entry = RemoveHeadList(&TempList);
00461         CatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink);
00462 
00463         /* Remove it */
00464         Catalog->ItemCount--;
00465         WsNcEntryDereference(CatalogEntry);
00466     }
00467 }
00468 
00469 INT
00470 WSAAPI
00471 WsNcGetCatalogFromProviderId(IN PNSCATALOG Catalog,
00472                              IN LPGUID ProviderId,
00473                              OUT PNSCATALOG_ENTRY *CatalogEntry)
00474 {
00475     PLIST_ENTRY NextEntry = Catalog->CatalogList.Flink;
00476     PNSCATALOG_ENTRY Entry;
00477 
00478     /* Lock the catalog */
00479     WsNcLock();
00480 
00481     /* Match the Id with all the entries in the List */
00482     while (NextEntry != &Catalog->CatalogList)
00483     {
00484         /* Get the Current Entry */
00485         Entry = CONTAINING_RECORD(NextEntry, NSCATALOG_ENTRY, CatalogLink);
00486         NextEntry = NextEntry->Flink;
00487 
00488         /* Check if this is the Catalog Entry ID we want */
00489         if (!(memcmp(&Entry->ProviderId, ProviderId, sizeof(GUID))))
00490         {
00491             /* Check if it doesn't already have a provider */
00492             if (!Entry->Provider)
00493             {
00494                 /* Match, load the Provider */
00495                 WsNcLoadProvider(Catalog, Entry);
00496             }
00497 
00498             /* Reference the entry and return it */
00499             InterlockedIncrement(&Entry->RefCount);
00500             *CatalogEntry = Entry;
00501             break;
00502         }
00503     }
00504 
00505     /* Release the catalog */
00506     WsNcUnlock();
00507 
00508     /* Return */
00509     return ERROR_SUCCESS;
00510 }
00511 
00512 BOOL
00513 WSAAPI
00514 WsNcMatchProtocols(IN DWORD NameSpace,
00515                    IN LONG AddressFamily,
00516                    IN LPWSAQUERYSETW QuerySet)
00517 {
00518     DWORD ProtocolCount = QuerySet->dwNumberOfProtocols;
00519     LPAFPROTOCOLS AfpProtocols = QuerySet->lpafpProtocols;
00520     LONG Family;
00521 
00522     /* Check for valid family */
00523     if (AddressFamily != -1)
00524     {
00525         /* Check if it's the magic */
00526         if (AddressFamily == AF_UNSPEC) return TRUE;
00527         Family = AddressFamily;
00528     }
00529     else
00530     {
00531         /* No family given, check for namespace */
00532         if (NameSpace == NS_SAP)
00533         {
00534             /* Use IPX family */
00535             Family = AF_IPX;
00536         }
00537         else
00538         {
00539             /* Other namespace, it's valid */
00540             return TRUE;
00541         }
00542     }
00543 
00544     /* Now try to get a match */
00545     while (ProtocolCount--)
00546     {
00547         /* Check this protocol entry */
00548         if ((AfpProtocols->iAddressFamily == AF_UNSPEC) ||
00549             (AfpProtocols->iAddressFamily == Family))
00550         {
00551             /* Match found */
00552             return TRUE;
00553         }
00554 
00555         /* Move to the next one */
00556         AfpProtocols++;
00557     }
00558 
00559     /* No match */
00560     return FALSE;
00561 }
00562 
00563 VOID
00564 WSAAPI
00565 WsNcRemoveCatalogItem(IN PNSCATALOG Catalog,
00566                       IN PNSCATALOG_ENTRY Entry)
00567 {
00568     /* Remove the entry from the list */
00569     RemoveEntryList(&Entry->CatalogLink);
00570 
00571     /* Decrease our count */
00572     Catalog->ItemCount--;
00573 }
00574 
00575 VOID
00576 WSAAPI
00577 WsNcDelete(IN PNSCATALOG Catalog)
00578 {
00579     PLIST_ENTRY Entry;
00580     PNSCATALOG_ENTRY CatalogEntry;
00581 
00582     /* Check if we're initialized */
00583     if (!Catalog->CatalogList.Flink) return;
00584 
00585     /* Acquire lock */
00586     WsNcLock();
00587 
00588     /* Loop every entry */
00589     Entry = Catalog->CatalogList.Flink;
00590     while (Entry != &Catalog->CatalogList)
00591     {
00592         /* Get this entry */
00593         CatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink);
00594 
00595         /* Remove it */
00596         WsNcRemoveCatalogItem(Catalog, CatalogEntry);
00597 
00598         /* Dereference it */
00599         WsNcEntryDereference(CatalogEntry);
00600 
00601         /* Move to the next entry */
00602         Entry = Catalog->CatalogList.Flink;
00603     }
00604 
00605     /* Check if the catalog key is opened */
00606     if (Catalog->CatalogKey)
00607     {
00608         /* Close it */
00609         RegCloseKey(Catalog->CatalogKey);
00610         Catalog->CatalogKey = NULL;
00611     }
00612 
00613     /* Release and delete the lock */
00614     WsNcUnlock();
00615     DeleteCriticalSection((LPCRITICAL_SECTION)&Catalog->Lock);
00616 
00617     /* Delete the object */
00618     HeapFree(WsSockHeap, 0, Catalog);
00619 }

Generated on Sun May 27 2012 04:27:10 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.