Name Resolution Data Structures in the SPI
A version of this page is also available for
4/8/2010
The WSAQUERYSET structure is used to form queries for NSPLookupServiceBegin, and used to deliver query results for NSPLookupServiceNext. It is a complex structure because it contains pointers to several other structures, some of which reference still other structures. The relationship between WSAQUERYSET and the structures it references is described in the following sections.
Within the WSAQUERYSET structure, most of the members are self explanatory, but some deserve additional explanation. The dwSize will be completed with sizeof(WSAQUERYSET), and can be used by namespace providers to detect and adapt to different versions of the WSAQUERYSET structure that may appear over time.
The dwOutputFlags member is used by a namespace provider to provide additional information about query results. For more information, see NSPLookupServiceNext.
The WSAECOMPARATOR structure referenced by lpversion is used for both query constraint and results. For queries, the dwVersion member indicates the desired version of the service. The ecHowmember is an enumerated type that specifies how the comparison will be made. The choices are COMP_EQUALS, which requires that an exact match in version occurs, or COMP_NOTLESS, which specifies that the service's version number is no less than the value of dwVersion.
The interpretation of dwNameSpaceand lpNSProviderId depends on how the structure is being used and is described further in the individual function descriptions that utilize this structure.
The lpszContext member applies to hierarchical namespaces, and specifies the starting point of a query or the location within the hierarchy where the service resides. The following list describes the general rules:
- A value of NULL, blank ("") will start the search at the default context.
- A value of "\" starts the search at the top of the namespace.
- Any other value starts the search at the designated point.
Providers that do not support containment may return an error if anything other than "" or "\" is specified. Providers that support limited containment, such as groups, should accept "", '\", or a designated point. Contexts are namespace specific. If dwNameSpace is NS_ALL, then only "" or "\" should be passed as the context, because these are recognized by all namespaces.
The lpszQueryString member is used to supply additional, namespace-specific query information such as a string describing a well-known service and transport protocol name, as in ftp/tcp.
The AFPROTOCOLS structure referenced by lpafpProtocols is used for query purposes only, and supplies a list of protocols to constrain the query. These protocols are represented as (address family, protocol) pairs, because protocol values only have meaning within the context of an address family.
The array of CSADDR_INFO structure referenced by lpcsaBuffer contains all of the information needed for either a service to use in establishing a listen, or a client to use in establishing a connection to the service. The LocalAddr and RemoteAddr members both directly contain a SOCKET_ADDRESS structure. A service would create a socket using the tuple (LocalAddr.lpSockaddr->sa_family, iSocketType, iProtocol). It would bind the socket to a local address using LocalAddr.lpSockaddr, and LocalAddr.lpSockaddrLength. The client creates its socket with the tuple (RemoteAddr.lpSockaddr->sa_family, iSocketType, iProtocol), and uses the combination of RemoteAddr.lpSockaddr, and RemoteAddr.lpSockaddrLength when making a remote connection.
Service Class Data Structures in the SPI
When a new service class is installed, a WSASERVICECLASSINFO structure must be prepared and supplied. This structure also consists of substructures that contain a series of parameters that apply to specific namespaces.
For each service class, there is a single WSASERVICECLASSINFO structure. Within the WSASERVICECLASSINFO structure, the service class's unique identifier is contained in lpServiceClassId, and an associated display string is referenced by lpServiceClassName.
The lpClassInfos member in the WSASERVICECLASSINFO structure references an array of WSANSCLASSINFO structures, each of which supplies a named and typed parameter that applies to a specified namespace. Examples of values for the lpszName member include: SAPID, TCPPORT, UDPPORT, and so on. These strings are generally specific to the namespace identified in dwNameSpace. Typical values for dwValueType might be REG_DWORD, REG_SZ, and so on. The dwValueSize member indicates the length of the data item pointed to by lpValue.
The entire collection of data represented in a WSASERVICECLASSINFO structure is provided to each namespace provider using NSPInstallServiceClass. Each individual namespace provider then sifts through the list of WSANSCLASSINFO structures and retains the information applicable to it. This architecture also envisions the future existence of a special namespace provider that would retain all of the service class schema information for all of the namespaces. Ws2.dll would query this provider to obtain the WSASERVICECLASSINFO data needed to supply to namespace providers when NSPLookupServiceBegin is invoked to initiate a query, and when NSPSetService is invoked to register a service. Namespace provider should not rely on this capability for the time being, and should instead have a provider-specific means to obtain any needed service class schema information. In the absence of a provider that stores all service class schemas for all namespaces, Ws2.dll will use NSPGetServiceClassInfo to obtain such information from each individual namespace provider.