static bool read_literal(SerdReader* reader, Ref* dest, Ref* datatype, Ref* lang, SerdNodeFlags* flags, bool* ate_dot) { Ref str = read_String(reader, flags); if (!str) { return false; } switch (peek_byte(reader)) { case '@': eat_byte_safe(reader, '@'); TRY_THROW(*lang = read_LANGTAG(reader)); break; case '^': eat_byte_safe(reader, '^'); eat_byte_check(reader, '^'); TRY_THROW(read_iri(reader, datatype, ate_dot)); break; } *dest = str; return true; except: pop_node(reader, *datatype); pop_node(reader, *lang); pop_node(reader, str); return false; }
static bool read_predicateObjectList(SerdReader* reader, ReadContext ctx, bool* ate_dot) { uint8_t c; while (true) { TRY_THROW(read_verb(reader, &ctx.predicate)); read_ws_star(reader); TRY_THROW(read_objectList(reader, ctx, ate_dot)); ctx.predicate = pop_node(reader, ctx.predicate); if (*ate_dot) { return true; } do { read_ws_star(reader); switch (c = peek_byte(reader)) { case 0: return false; case '.': case ']': return true; case ';': eat_byte_safe(reader, c); } } while (c == ';'); } pop_node(reader, ctx.predicate); return true; except: pop_node(reader, ctx.predicate); return false; }
static bool read_number(SerdReader* reader, Ref* dest, Ref* datatype, bool* ate_dot) { #define XSD_DECIMAL NS_XSD "decimal" #define XSD_DOUBLE NS_XSD "double" #define XSD_INTEGER NS_XSD "integer" Ref ref = push_node(reader, SERD_LITERAL, "", 0); uint8_t c = peek_byte(reader); bool has_decimal = false; if (c == '-' || c == '+') { push_byte(reader, ref, eat_byte_safe(reader, c)); } if ((c = peek_byte(reader)) == '.') { has_decimal = true; // decimal case 2 (e.g. '.0' or `-.0' or `+.0') push_byte(reader, ref, eat_byte_safe(reader, c)); TRY_THROW(read_0_9(reader, ref, true)); } else { // all other cases ::= ( '-' | '+' ) [0-9]+ ( . )? ( [0-9]+ )? ... TRY_THROW(is_digit(c)); read_0_9(reader, ref, true); if ((c = peek_byte(reader)) == '.') { has_decimal = true; // Annoyingly, dot can be end of statement, so tentatively eat eat_byte_safe(reader, c); c = peek_byte(reader); if (!is_digit(c) && c != 'e' && c != 'E') { *dest = ref; *ate_dot = true; // Force caller to deal with stupid grammar return true; // Next byte is not a number character, done } push_byte(reader, ref, '.'); read_0_9(reader, ref, false); } } c = peek_byte(reader); if (c == 'e' || c == 'E') { // double push_byte(reader, ref, eat_byte_safe(reader, c)); switch ((c = peek_byte(reader))) { case '+': case '-': push_byte(reader, ref, eat_byte_safe(reader, c)); default: break; } TRY_THROW(read_0_9(reader, ref, true)); *datatype = push_node(reader, SERD_URI, XSD_DOUBLE, sizeof(XSD_DOUBLE) - 1); } else if (has_decimal) { *datatype = push_node(reader, SERD_URI, XSD_DECIMAL, sizeof(XSD_DECIMAL) - 1); } else { *datatype = push_node(reader, SERD_URI, XSD_INTEGER, sizeof(XSD_INTEGER) - 1); } *dest = ref; return true; except: pop_node(reader, *datatype); pop_node(reader, ref); return false; }
// Recurses, calling statement_sink for every statement encountered. // Leaves stack in original calling state (i.e. pops everything it pushes). static bool read_object(SerdReader* reader, ReadContext ctx, bool* ate_dot) { static const char* const XSD_BOOLEAN = NS_XSD "boolean"; static const size_t XSD_BOOLEAN_LEN = 40; #ifndef NDEBUG const size_t orig_stack_size = reader->stack.size; #endif bool ret = false; bool emit = (ctx.subject != 0); SerdNode* node = NULL; Ref o = 0; Ref datatype = 0; Ref lang = 0; uint32_t flags = 0; const uint8_t c = peek_byte(reader); switch (c) { case '\0': case ')': return false; case '[': emit = false; TRY_THROW(ret = read_anon(reader, ctx, false, &o)); break; case '(': emit = false; TRY_THROW(ret = read_collection(reader, ctx, &o)); break; case '_': TRY_THROW(ret = (o = read_BLANK_NODE_LABEL(reader, ate_dot))); break; case '<': case ':': TRY_THROW(ret = read_iri(reader, &o, ate_dot)); break; case '+': case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': TRY_THROW(ret = read_number(reader, &o, &datatype, ate_dot)); break; case '\"': case '\'': TRY_THROW(ret = read_literal(reader, &o, &datatype, &lang, &flags, ate_dot)); break; default: /* Either a boolean literal, or a qname. Read the prefix first, and if it is in fact a "true" or "false" literal, produce that instead. */ node = deref(reader, o = push_node(reader, SERD_CURIE, "", 0)); while (read_PN_CHARS_BASE(reader, o)) {} if ((node->n_bytes == 4 && !memcmp(node->buf, "true", 4)) || (node->n_bytes == 5 && !memcmp(node->buf, "false", 5))) { node->type = SERD_LITERAL; datatype = push_node( reader, SERD_URI, XSD_BOOLEAN, XSD_BOOLEAN_LEN); ret = true; } else if (read_PN_PREFIX_tail(reader, o) > SERD_FAILURE) { ret = false; } else { ret = read_PrefixedName(reader, o, false, ate_dot); } } if (ret && emit) { deref(reader, o)->flags = flags; ret = emit_statement(reader, ctx, o, datatype, lang); } except: pop_node(reader, lang); pop_node(reader, datatype); pop_node(reader, o); #ifndef NDEBUG assert(reader->stack.size == orig_stack_size); #endif return ret; }
INT WSAAPI WSCInstallNameSpace ( IN LPWSTR lpszIdentifier, IN LPWSTR lpszPathName, IN DWORD dwNameSpace, IN DWORD dwVersion, IN LPGUID lpProviderId ) /*++ Routine Description: WSCInstallNameSpace() is used to install a name space provider. For providers that are able to support multiple names spaces, this function must be called once for every name space supported, and a unique provider ID must be supplied each time. Arguments: lpszIdentifier - Display string for the provider. lpszPathname - Points to a path to the providers DLL image which follows the usual rules for path resolution. This path may contain embedded environment strings (such as %SystemRoot%). Such environment strings are expanded whenever the WinSock 2 DLL needs to subsequently load theprovider DLL on behalf of an application. After any embedded environment strings are expanded, the WinSock 2 DLL passes the resulting string into the LoadLibrary() function to load the provider into memory. dwNameSpace - Specifies the name space supported by this provider. dwVersion - Specifies the version number of the provider. bStoresAllServiceClassInfo - Specifies that this provider supports the storage of service class schema information for all service classes across all namespaces. The Winsock DLL will then use this provider to get all of its classinfo information rather than asking each individual provider. lpProviderId - A unique identifier for this provider. This GUID should be generated by UUIDGEN.EXE. Return Value: The function should return NO_ERROR (0) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError(). --*/ { INT ReturnCode; PNSCATALOG Catalog =NULL; PNSCATALOGENTRY Item =NULL; HKEY registry_root; BOOL lock_owned = FALSE; registry_root = OpenWinSockRegistryRoot(); if (NULL == registry_root) { DEBUGF( DBG_ERR, ("Opening registry root\n")); SetLastError(WSASYSCALLFAILURE); return(SOCKET_ERROR); } // // Check the current protocol catalog key. If it doesn't match // the expected value, blow away the old key and update the // stored value. // ValidateCurrentCatalogName( registry_root, WINSOCK_CURRENT_NAMESPACE_CATALOG_NAME, NSCATALOG::GetCurrentCatalogName() ); TRY_START(guard_memalloc){ GUID_MATCH_CONTEXT context; Catalog = new NSCATALOG; if (NULL == Catalog){ ReturnCode = WSA_NOT_ENOUGH_MEMORY; TRY_THROW(guard_memalloc); } //item Item = new NSCATALOGENTRY; if (NULL == Item){ ReturnCode = WSA_NOT_ENOUGH_MEMORY; TRY_THROW(guard_memalloc); } //if __try { context.ProviderId = *lpProviderId; ReturnCode = Item->InitializeFromValues( lpszPathName, lpszIdentifier, lpProviderId, dwNameSpace, dwVersion ); } __except (WS2_EXCEPTION_FILTER()) { ReturnCode = WSAEFAULT; TRY_THROW(guard_memalloc); } if (ERROR_SUCCESS != ReturnCode){ TRY_THROW(guard_memalloc); } //if ReturnCode = Catalog->InitializeFromRegistry( registry_root, // ParentKey NULL // ChangeEvent ); if (ERROR_SUCCESS != ReturnCode){ TRY_THROW(guard_memalloc); } //if context.CatalogItem = NULL; Catalog->EnumerateCatalogItems( GuidMatcher, &context ); if (context.CatalogItem != NULL){ ReturnCode = WSAEINVAL; TRY_THROW(guard_memalloc); } //if Catalog->AppendCatalogItem( Item ); Item = NULL; // item deletion is now covered by catalog ReturnCode = Catalog->WriteToRegistry(); if (ReturnCode!=ERROR_SUCCESS) { TRY_THROW (guard_memalloc); } delete Catalog; } TRY_CATCH(guard_memalloc){ assert (ReturnCode!=ERROR_SUCCESS); if (Item){ Item->Dereference (); } //if if (Catalog){ delete Catalog; } //if } TRY_END(guard_memalloc); CloseWinSockRegistryRoot(registry_root); if (ReturnCode == ERROR_SUCCESS) { HANDLE hHelper; // // Alert all interested apps of change via the notification method // if (WahOpenNotificationHandleHelper( &hHelper )==ERROR_SUCCESS) { WahNotifyAllProcesses( hHelper ); WahCloseNotificationHandleHelper( hHelper ); } else { // This is non-fatal and catalog was updated anyway } return ERROR_SUCCESS; } else { SetLastError(ReturnCode); return SOCKET_ERROR; } }
int WSPAPI WSCWriteNameSpaceOrder ( IN LPGUID lpProviderId, IN DWORD dwNumberOfEntries ) /*++ Routine Description: Reorder existing WinSock2 name space providers. The order of the service providers determines their priority in being selected for use. The sporder.exe tool will show you the installed provider and their ordering, Alternately, WSAEnumNameSpaces(), in conjunction with this function, will allow you to write your own tool. Arguments: lpwdCatalogEntryId [in] An array of CatalogEntryId elements as found in the WSAPROTOCOL_INFO structure. The order of the CatalogEntryId elements is the new priority ordering for the service providers. dwNumberOfEntries [in] The number of elements in the lpwdCatalogEntryId array. Return Value: ERROR_SUCCESS - the service providers have been reordered. WSAEINVAL - input parameters were bad, no action was taken. WSAEFAULT - CatalogEnryId array is not fully contained within process address space. WSATRY_AGAIN - the routine is being called by another thread or process. any registry error code Comments: Here are scenarios in which the WSCWriteProviderOrder function may fail: The dwNumberOfEntries is not equal to the number of registered service providers. The lpwdCatalogEntryId contains an invalid catalog ID. The lpwdCatalogEntryId does not contain all valid catalog IDs exactly 1 time. The routine is not able to access the registry for some reason (e.g. inadequate user persmissions) Another process (or thread) is currently calling the routine. --*/ { INT errno_result; HKEY registry_root; PNSCATALOGENTRY item; PNSCATALOGENTRY *items = NULL; DWORD i; // object protected by "try" block PNSCATALOG catalog = NULL; items = new PNSCATALOGENTRY[dwNumberOfEntries]; if (items==NULL) { DEBUGF( DBG_ERR, ("Allocating items array\n")); return WSA_NOT_ENOUGH_MEMORY; } memset (items, 0, sizeof (PNSCATALOGENTRY)*dwNumberOfEntries); errno_result = ERROR_SUCCESS; TRY_START(guard_memalloc) { PROVIDER_SNAP_CONTEXT context; registry_root = OpenWinSockRegistryRoot(); if (registry_root == NULL) { DEBUGF( DBG_ERR, ("Opening registry root\n")); errno_result = WSANO_RECOVERY; TRY_THROW(guard_memalloc); } catalog = new NSCATALOG(); if (catalog == NULL) { errno_result = WSA_NOT_ENOUGH_MEMORY; TRY_THROW(guard_memalloc); } errno_result = catalog->InitializeFromRegistry( registry_root, // ParentKey NULL // ChangeEvent ); if (errno_result != ERROR_SUCCESS) { TRY_THROW(guard_memalloc); } context.Items = items; context.ProviderIds = lpProviderId; context.Count = dwNumberOfEntries; context.ErrorCode = ERROR_SUCCESS; catalog->EnumerateCatalogItems( ProviderSnap, // Iteration & context // PassBack ); if (context.ErrorCode!=ERROR_SUCCESS) { errno_result = context.ErrorCode; TRY_THROW(guard_memalloc); } for (i=0; i<dwNumberOfEntries; i++) { if (context.Items[i]!=NULL) { // // Remove catalog item and add it in the end. // catalog->RemoveCatalogItem (context.Items[i]); catalog->AppendCatalogItem (context.Items[i]); } else { DEBUGF (DBG_ERR, ("Checking item array against catalog, item: %ld.\n", i)); errno_result = WSAEINVAL; TRY_THROW(guard_memalloc); } } // for i errno_result = catalog->WriteToRegistry(); if (errno_result!=ERROR_SUCCESS) { TRY_THROW(guard_memalloc); } delete catalog; CloseWinSockRegistryRoot(registry_root); } TRY_CATCH(guard_memalloc) { assert (errno_result != ERROR_SUCCESS); if (catalog != NULL) { delete catalog; // This destroys the items as well } if (registry_root!=NULL) { CloseWinSockRegistryRoot(registry_root); } } TRY_END(guard_memalloc); delete items; if (errno_result == ERROR_SUCCESS) { HANDLE hHelper; // // Alert all interested apps of change via the notification method // if (WahOpenNotificationHandleHelper( &hHelper) == ERROR_SUCCESS) { WahNotifyAllProcesses( hHelper ); WahCloseNotificationHandleHelper( hHelper ); } else { // // This in non-fatal and catalog was updated anyway. // } } return errno_result; }
INT WSAAPI WSCEnableNSProvider ( IN LPGUID lpProviderId, IN BOOL fEnable ) /*++ Routine Description: WSCEnableNSProvider() is used to change the state of a given name space provider. This function is intended to be used by the control panel applet to change the state of the providers. An ISV should not just blindly de-activate another ISV's provider in order to activate their own. This choice should be left up to the user.description-of-function Arguments: lpProviderId - The unique identifier for this provider. fEnable - If TRUE, the provider is set to the active state. If FALSE, the provider is disabled and will not be available for query operations or service registration. Return Value: The function should return NO_ERROR (0) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError(). --*/ { INT ReturnCode; PNSCATALOG Catalog =NULL; HKEY registry_root; registry_root = OpenWinSockRegistryRoot(); if (NULL == registry_root) { DEBUGF( DBG_ERR, ("Opening registry root\n")); SetLastError(WSASYSCALLFAILURE); return(SOCKET_ERROR); } TRY_START(guard_memalloc){ GUID_MATCH_CONTEXT context; Catalog = new NSCATALOG; if (NULL == Catalog){ ReturnCode = WSA_NOT_ENOUGH_MEMORY; TRY_THROW(guard_memalloc); } //item ReturnCode = Catalog->InitializeFromRegistry( registry_root, // ParentKey NULL // ChangeEvent ); if (ERROR_SUCCESS != ReturnCode){ TRY_THROW(guard_memalloc); } //if __try { context.ProviderId = *lpProviderId; } __except (WS2_EXCEPTION_FILTER()) { ReturnCode = WSAEFAULT; TRY_THROW(guard_memalloc); } context.CatalogItem = NULL; Catalog->EnumerateCatalogItems( GuidMatcher, &context); if (context.CatalogItem!=NULL) { context.CatalogItem->Enable (fEnable ? TRUE : FALSE); } else { ReturnCode = WSAEINVAL; TRY_THROW(guard_memalloc); } ReturnCode = Catalog->WriteToRegistry(); if (ReturnCode != ERROR_SUCCESS) { TRY_THROW(guard_memalloc); } delete Catalog; } TRY_CATCH(guard_memalloc){ assert (ReturnCode!=ERROR_SUCCESS); if (Catalog){ delete Catalog; } //if } TRY_END(guard_memalloc); CloseWinSockRegistryRoot(registry_root); if (ERROR_SUCCESS == ReturnCode){ HANDLE hHelper; // // Alert all interested apps of change via the notification method // if (WahOpenNotificationHandleHelper( &hHelper) == ERROR_SUCCESS) { WahNotifyAllProcesses( hHelper ); WahCloseNotificationHandleHelper( hHelper ); } else { // // This in non-fatal and catalog was updated anyway. // } return ERROR_SUCCESS; } else { SetLastError(ReturnCode); return SOCKET_ERROR; } }
INT WSAAPI WSCUnInstallNameSpace ( IN LPGUID lpProviderId ) /*++ Routine Description: WSCUnInstallNameSpace() is used to uninstall the indicated name space provider. Arguments: lpProviderId - The unique identifier for a provider. Return Value: The function should return NO_ERROR (0) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError(). --*/ { INT ReturnCode; PNSCATALOG Catalog =NULL; HKEY registry_root; //Open and Initialize a name space jprovider catalog registry_root = OpenWinSockRegistryRoot(); if (NULL == registry_root) { DEBUGF( DBG_ERR, ("Opening registry root\n")); SetLastError(WSASYSCALLFAILURE); return(SOCKET_ERROR); } TRY_START(guard_memalloc){ GUID_MATCH_CONTEXT context; Catalog = new NSCATALOG; if (NULL == Catalog){ ReturnCode = WSA_NOT_ENOUGH_MEMORY; TRY_THROW(guard_memalloc); } //item ReturnCode = Catalog->InitializeFromRegistry( registry_root, // ParentKey NULL // ChangeEvent ); if (ERROR_SUCCESS != ReturnCode){ TRY_THROW(guard_memalloc); } //if __try { context.ProviderId = *lpProviderId; } __except (WS2_EXCEPTION_FILTER()) { ReturnCode = WSAEFAULT; TRY_THROW(guard_memalloc); } context.CatalogItem = NULL; Catalog->EnumerateCatalogItems( GuidMatcher, &context); if (context.CatalogItem!=NULL) { Catalog->RemoveCatalogItem (context.CatalogItem); context.CatalogItem->Dereference (); } else { ReturnCode = WSAEINVAL; TRY_THROW(guard_memalloc); } ReturnCode = Catalog->WriteToRegistry(); if (ERROR_SUCCESS != ReturnCode){ TRY_THROW(guard_memalloc); } //if delete Catalog; } TRY_CATCH(guard_memalloc){ assert (ReturnCode!=ERROR_SUCCESS); if (Catalog){ delete Catalog; } //if } TRY_END(guard_memalloc); CloseWinSockRegistryRoot(registry_root); if (ERROR_SUCCESS == ReturnCode){ HANDLE hHelper; // // Alert all interested apps of change via the notification method // if (WahOpenNotificationHandleHelper( &hHelper) == ERROR_SUCCESS) { WahNotifyAllProcesses( hHelper ); WahCloseNotificationHandleHelper( hHelper ); } else { // // This in non-fatal and catalog was updated anyway. // } return ERROR_SUCCESS; } else { SetLastError(ReturnCode); return SOCKET_ERROR; } }