Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygennscatalo.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
1.7.6.1
|