Legal Information

[This is preliminary documentation and subject to change.]

Generic Quality of Service (GQOS)

This is a preliminary document and may be changed substantially prior to final commercial release. This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document. Information in this document is subject to change without notice. The entire risk of the use or the results of the use of this document remains with the user. The names of companies, products, people, characters, and/or data mentioned herein are fictitious and are in no way intended to represent any real individual, company, product, or event, unless otherwise noted. Complying with all applicable copyright laws is the responsibility of the user. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Microsoft Corporation.

Portions of this document specify and accompany software that is still in development. Some of the information in this documentation may be inaccurate or may not be an accurate representation of the functionality of final documentation or software. Microsoft assumes no responsibility for any damages that might occur directly or indirectly from these inaccuracies.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

© 1998 Microsoft Corporation. All rights reserved.

Microsoft, MS-DOS, MS, Windows, Windows NT, and Win32 are either registered trademarks or trademarks of Microsoft Corporation in the U.S.A. and/or other countries.

Other product and company names mentioned herein may be the trademarks of their respective owners.


How to Use the GQOS Documentation

[This is preliminary documentation and subject to change.]

This section discusses the following topics.

  • GQOS Documentation Structure
  • Determining Which Discussion Is for You


GQOS Documentation Structure

[This is preliminary documentation and subject to change.]

To facilitate explanation, the Generic Quality of Service (GQOS) documentation divides the GQOS components into three categories:

  • Application-Driven GQOS Components
  • Network-Driven GQOS Components
  • Policy-Driven GQOS Components

This division is purely for the sake of convenience and clarity. Though each of these GQOS components is in some way initiated at the client or end-node, and in pure semantics, is initiated by the application, the impact of the component may be greatest elsewhere.

For an example (which may be clearer once the 802.1p GQOS component is further explained), the 802.1p precedence bits are actually set in the end-node's network stack, and is done so because an application initiated a sequence of GQOS events that eventually triggered the setting of the bits. The cause of this bit-setting, then, could be argued to be the application's initiation of GQOS service (thus application-driven). However, because the effect of setting the priority on 802.1p bits has the greatest impact when the packets associated with this session cross their local segment, 802.1p is included in the Network-Driven GQOS Components category, and not in the Application-Driven GQOS Components category. Despite the fact that no quality of service requests would have been instigated to set the 802.1p bit without the application's invocation of a GQOS component, its explanation is best placed in a discussion of network-driven components. The ripple-effect of 802.1p bit setting, then, is felt greatest in the network.

Although individual components from among the three categories can function independently at times to provide subsets of QOS functionality, GQOS overall is an integrated technology.

The following figure provides a visual representation of the structure of GQOS documentation, and the reasoning behind its structure; certain GQOS components have greatest impact in one of the three categories, and are thus discussed there:


Determining Which Discussion Is for You

[This is preliminary documentation and subject to change.]

Most developers of GQOS-enabled applications will find their requirements met within the GQOS API, and the requisite knowledge of components will fall largely under the Application-Driven GQOS Components section. Thus, reading through the Application-Driven GQOS Components overview material, combined with the API reference information in GQOS Reference, should provide nearly all of the information necessary to develop GQOS-aware applications.

There is other information available within the other sections found within this GQOS documentation that facilitates the development of granular Traffic Control, such as that found in the Network-Driven GQOS Components section, that can provide explanations of the underlying technologies and programmatic reference to interfaces available for such efforts. In such circumstances, a reading of the Application-Driven and Network-Driven sections is suggested.

For development of policy components, such as third party authentication services intended to provide network resource admission services, the Policy-Driven sections are likely best candidates.

For a complete understanding of GQOS and its components, as they are implemented and interact within the Windows NT® 5.0 (and Windows 98) framework, reading of all of the overview sections is recommended.


About GQOS

[This is preliminary documentation and subject to change.]

GQOS is a collection of components that enable differentiation and preferential treatment for subsets of data transmitted over the network. GQOS is Microsoft's implementation of Quality of Service (QOS); Quality of Service is a defined term that loosely means subsets of data get higher priority or guaranteed "service" when traversing a network.

GQOS technology has implications for the application programmer and the network administrator. By writing QOS enabled-applications, programmers can:

  • Specify or request bandwidth requirements particular to their application, such as latency requirements for streaming audio.
  • Write mission-critical applications for the corporate environment that are guaranteed to get their required bandwidth, provided permissions and bandwidth availability exist.

Just as importantly, network administrators can leverage knowledge of GQOS to achieve the following:

  • Control network device resources based on user permissions and/or application usage.
  • Reserve portions of a given bandwidth, whether an Ethernet subnet or a WAN interface, for applications or users that require such availability for core business activities.
  • Shape and smooth the traffic that clients submit to the network, thereby avoiding the overburdening of switches and routers suffered with traditional bursty transmissions.

GQOS achieves this through programmatic interfaces, the cooperation of multiple components, and communication with network devices throughout the end-to-end network solution.


Introduction to GQOS

[This is preliminary documentation and subject to change.]

If you've ever endured impromptu demonstrations of cool new software touting jittery, real-time audio and video to the desktop (gobbling megabits per second on the already-taxed local LAN segment, corporate network backbone, WAN, and video server's subnet), only to find your mission-critical file transfer is inching along at a pace that ensures you'll miss your deadline, you may be interested in Quality of Service, or QOS. If you're the network administrator, charged with ensuring mission-critical applications have sufficient bandwidth to keep the company functioning, while content junkies unwittingly flood the network with multimedia application data, you too may be interested in QOS.

This section contains information on the following topics:

  • Quality of Service Defined
  • Generic Quality of Service Defined
  • What GQOS Solves


Quality of Service Defined

[This is preliminary documentation and subject to change.]

Quality of Service (QOS) provides applications (or network administrators) with a means by which network resources, such as available bandwidth and latency performance, can be predicted and managed on both local machines and devices throughout the network.

With such an all-network encompassing definition, QOS functionality requires cooperation among and between end nodes, switches, routers, and WAN links through which data must pass. Without some level of cooperation among those network devices, the quality of data transmission services would potentially break down. In other words, if each of the above network devices were left to make its own decisions about transmitting data, it would likely treat all data equally, and thus provide simple first-come first-served service. Although such service may be satisfactory in network devices or transmission mediums that are not heavily loaded, when congestion occurs, such equal treatment could mean all data passing through the device would get delayed. With this information, we can extend the definition of QOS, by adding that quality of service allows preferential treatment for certain subsets of data as it traverses any QOS-enabled part of (or device in) the network.

Windows NT® 5.0 implements quality of service by including a number of components, each of which potentially cooperates with (or invokes) one another. These components are found in the incarnation of DLLs, protocols, NT services and individual network device functionality.


Generic Quality of Service Defined

[This is preliminary documentation and subject to change.]

Microsoft's implementation of quality of service is called Generic Quality of Service (GQOS), so named because its design enables developers to use generic Windows Sockets 2 calls to create QOS-enabled applications.

With GQOS, developers do not need to consider how the various operating system components interact to achieve quality of service. The components that comprise quality of service implementation are instead abstracted from the QOS application development effort, allowing a single, or generic, QOS interface instead of individual interfaces to each QOS component. This provides a generic interface for the developer, and also provides a mechanism by which new QOS components (perhaps with added functionality) can be added, without the need to completely rewrite existing QOS applications.


What GQOS Solves

[This is preliminary documentation and subject to change.]

As computing and applications become more mission-critical, not to mention more content-rich and multimedia centric, the bandwidth necessary to service desktop functionality increases. However, bandwidth availability doesn't keep up with the bandwidth appetite of today's desktop applications, creating an environment where there is often more data to be transmitted than there are resources to transmit that data. The "bursty" nature of network transmissions only contributes to the problem.

Traditional data transfers are also increasing as a result of a continual addition of new network nodes to the existing network. At the crux of this problem is the fact that there is no inherent means of differentiating between "important data," such as that transmitted by mission-critical applications, and "excessive data," such as that which may be transmitted by interesting (but not necessarily critical) multimedia applications.

Such traditional business applications are continuing to increase in size and in network use, but they aren't alone in their hunger for the network. New applications are pushing network utilization to its limits and sometimes beyond; such as multimedia applications, and they're making extensive use of the network. For example, video transmission applications require significant bandwidth to transmit with acceptable levels of quality. Due to the "send as much data as you can" nature of the most prevalent networking protocol, IP, even a few active instances of these data-intensive programs can put bandwidth strain onto networks that were never designed to carry it. With data-intensive multimedia applications putting such hefty data loads onto the network, the network often becomes less available for other applications. If the load is significant enough, overall network performance will wane.

Such network performance degradation is especially threatening to real-time audio and interactive conferencing transmissions; they are time-sensitive and especially susceptible to the introduction of delays or individual frame drops during the course of their delivery. Such delays in the delivery of individual packets, known as latency, can render real-time audio and real-time conferencing applications substandard at best, and a burden to even try using at worst.

In the midst of larger traditional applications' higher network utilization, as well as increased network use by emerging desktop applications, core business application are left vying, sometimes unsuccessfully, for adequate access to the network. These bandwidth-poor and latency-laden effects of an overburdened network have an even larger and more dramatic effect on mission-critical applications that may want to make use of new multimedia desktop technology: not only to they need access to the burdened network, they need more of the increasingly precious network resources, putting core business applications that use multimedia features in double jeopardy.

If such over-subscription of available network resources doesn't paint a bleak enough picture, the prevalence of Wide Area Networking can be added to the situation, introducing an even more critical and more precious bandwidth restriction at the WAN link. With this, the situation is exacerbated.

Thus to manage oversubscription of network resources, to regulate the allocation of available network resources, and to present network data in a means more friendly to a shared network environment (i.e., in a less bursty manner), mechanisms that help manage network activity from an end-to-end perspective are needed. These mechanisms are found in the blanket technology called GQOS.


How GQOS Works

[This is preliminary documentation and subject to change.]

To achieve manageable and predictable QOS from one end of the network to the other, the collection of components that must communicate and interact results in a fairly complex process. For just a few examples, GQOS has the intrinsic ability to facilitate priority along every step along a packet's journey: in the sender's network stack, at the switch, and even at each QOS-enabled router hop. GQOS also has the ability to facilitate how much data should and can be sent in a given length of time, maximum burst rates, and overall bandwidth utilization rights… which can be configured based on administratively configurable user rights. These functional capabilities only scratch the tip of the GQOS iceberg. GQOS is comprised of a number of components.

The following figure shows where many of the GQOS components reside in relation to the network stack, where communication occurs between and among them, and where certain interfaces such as APIs facilitate developing GQOS services.

Note that this is an individual node's network stack view, not a functional schematic of how GQOS operates over a given network. Some of these components have further defined subcomponents, each of which is explained under GQOS Components.


GQOS Components

[This is preliminary documentation and subject to change.]

To facilitate explanation, the GQOS documentation divides the GQOS components into the following three categories:

  • Application-Driven GQOS Components
  • Network-Driven GQOS Components
  • Policy-Driven GQOS Components

Note This segmentation is purely for convenience and clarity's sake: Though individual components from among the three categories can, in certain situations, function independently of each other to provide certain subsets of QOS functionality, GQOS overall is an integrated technology. For more information on how the documentation is organized, see GQOS Documentation Structure.

This is the approach taken with all GQOS components, with one exception: RSVP. Though the bulk of RSVP will be discussed within the Application-Driven GQOS Components category, elements which have effects elsewhere (namely in the network, and for facilitation of policy checking) will be included in their respective sections.


Application-Driven GQOS Components

[This is preliminary documentation and subject to change.]

GQOS Service Provider (GQOS SP)
The GQOS Service Provider facilitates GQOS and invokes other GQOS components.
Traffic Control Modules
Facilitators of traffic control. Includes the Packet Classifier, the Packet Scheduler, and the Packet Shaper.
Resource Reservation Protocol (RSVP)
Invoked by the GQOS SP, and the carrier of reserve requests across the entire network, with a functional interface for each QOS-enabled network device 'hop' across the network. Though important to overall GQOS technology, and to QOS in general, certain GQOS faculties do not require RSVP to operate, which means that Quality of Service can be achieved without RSVP signaling.
GQOS API
Programmatic interface to the GQOS SP.
Traffic Control API (TCAPI)
The Traffic Control API.


GQOS API

[This is preliminary documentation and subject to change.]

The GQOS API is the programmatic interface to the GQOS service provider (GQOS SP). Under most circumstances, the GQOS API is the only interface that programmers will require to create QOS-aware or QOS-enabled applications. The GQOS API is the hot-water drip in the virtual coffee-making system that is GQOS; (almost) all things that happen in the GQOS sequence are a result of GQOS API calls percolating down (and sometimes back up) through GQOS components, in the end creating fixed-bucket sized servings of data that help keep the network from getting lethargic.

For more information on the programming elements included in the GQOS API, see GQOS Reference.


GQOS Service Provider

[This is preliminary documentation and subject to change.]

The GQOS service provider (GQOS SP) is the GQOS component that invokes nearly all resulting QOS facilities. The GQOS SP instigates Traffic Control functionality (if appropriate), and implements, maintains, and handles RSVP signaling for all of GQOS functionality.

The GQOS SP, by virtue of the fact that it implements and maintains RSVP and is the initiator of Traffic Control, is at the heart of GQOS.


Traffic Control API

[This is preliminary documentation and subject to change.]

The Traffic Control API (TCAPI), is a programmatic interface to the Traffic Control components that regulate network traffic on local hosts; both from an internal perspective (within the kernel itself), and from a network perspective (prioritization and cueing of packets based on transmission priority).

Traffic Control is implicitly invoked through calls made to the GQOS API and subsequently serviced by the GQOS Service Provider (GQOS SP). However, applications that require further or specific control over Traffic Control can use the TCAPI. The GQOS SP also uses TCAPI calls.


Traffic Control Modules

[This is preliminary documentation and subject to change.]

Traffic Control (TC) plays a significant and central role in the provision of QOS. With Traffic Control, packets are prioritized both within and outside the "node" on which TC is used. The implications for such granular control (or preferential treatment) of packets, as they flow through the system and through the network, reach across the entire network realm or enterprise. Traffic Control is realized through three modules, the Generic Packet Classifier, the Packet Scheduler and the Packet Shaper.


Generic Packet Classifier

Packet classification provides a means by which packets internal to a specific network node can be classified, and consequently prioritized, within and by both user- and kernel-mode network components. Such classification and prioritization uses include activities such as CPU processing attention, or transmission onto the network. The Generic Packet Classifier (GPC) is utilized through an interface called the Generic Packet Classifier Interface, or GPC Interface, which facilitates an "information store" that can be used, or associated, with specified (defined) subsets of packets.

The GPC's importance hinges on its ability to provide lookup tables and classification services within the network stack, and is thus the first step in an overall and ubiquitous prioritization scheme for network traffic.


Packet Scheduler

Packet scheduling is the means by which data (packet) transmission-governing–a key function of GQOS–is achieved. The Packet Scheduler is the traffic control module that regulates how much data an application (or flow) is allowed, essentially enforcing GQOS parameters that are set for a particular flow. The Packet Scheduler incorporates three mechanisms in its scheduling of packets: A Conformer, the Packet Shaper, and a Sequencer. The Conformer and Sequencer are discussed in more detail when Traffic Control is treated in detail. Since the Packet Scheduler's importance is perhaps essential to overall Traffic Control understanding, it is defined here.

The Packet Scheduler considers the classification provided by the Generic Packet Classifier (GPC), and provides preferential treatment to higher-priority traffic. Consequently, the Packet Scheduler is the first step (in a sequential view) in ensuring that prioritized network transmission of packets begins with data that has been deemed most important.


Packet Shaper

The Packet Shaper mitigates the bursty nature of computer network transmissions by smoothing transmission peaks over a given period of time, thereby smoothing out network usage to affect a more steady use of the network. The significance of the Packet Shaper becomes apparent: one factor that contributes to network congestion is the bursty nature of computer data transmissions, a side-effect of the "send it all out right now" inherent nature of (TCP or UDP)/IP; packet shaping can take large strides in alleviating at least some of the effects of such activity by spacing out QOS-enabled packet transmissions.


Network-Driven GQOS Components

[This is preliminary documentation and subject to change.]

802.1p
The use of flags in the media access control (MAC) header to establish packet priority in shared-media 802 networks.
IP Precedence
Establishes priority for IP packets, used to establish packet priority in Layer 3 switches (routers).
L2 Signaling
The mapping of RSVP objects to Layer 2 (per the ISO OSI Model) signaling, such as Frame Relay Network Devices (FRNDs) or ATM interfaces.
Subnet Bandwidth Manager (SBM)
Manages shared-media network bandwidth. In GQOS, SBM functionality is incorporated in the Admission Control Service (ACS).
Resource Reservation Protocol (RSVP)
Carries and disseminates QOS information to QOS-aware network devices along the path between a sender and one or more receivers for a given flow.


802.1p

[This is preliminary documentation and subject to change.]

Responsibility for Quality of Service provisions on the local segment, and avoidance of the "all packets are treated equally" issue, falls onto the hub or switch servicing the segment. At such a level, the issue of differentiating between network packets, and perhaps treating them differently, must fall into the realm of the media access control (MAC) header. The MAC header (the lower half of Layer 2 in the ISO OSI Model) is the only part of a packet that hubs or switches investigate in their scope of work.

802.1p provides prioritization of packets traversing a subnet by the setting of a three-bit value in the MAC header. Thus, when the local segment becomes congested and the hub/switch workload results in the delay (or dropping) of packets, those packets with flags that correspond to higher priorities will receive preferential treatment, and will be serviced before packets with lower priorities.

Note that implementing 802.1p for QOS requires an 802.1p-aware network interface card, an 802.1p-aware device driver, and an 802.1p-aware switch.


IP Precedence

[This is preliminary documentation and subject to change.]

IP Precedence allows packets passing through core network devices that operate on Layer 3 information, such as routers, to have their relative priority differentiated from one another. IP Precedence is established by the setting of specific bits in the IP header. With IP Precedence, Layer 3 devices can establish precedence-based cues and provide better service (when packet service is subject to cueing, as is the case under significant traffic loads) to packets that have higher priority.

In order for IP Precedence to be effective, Layer 3 devices must be IP Precedence-enabled.


L2 Signaling

[This is preliminary documentation and subject to change.]

WAN technology manipulates Layer 1, Layer 2, and to a certain extent, Layer 3 information, as it transmits data over the Telecommunications network. Since GQOS is an end-to-end solution that provides quality of service for data transferred across the network, there must be a means by which data passing through WAN interfaces can be associated with some sort of preferential or non-preferential treatment. Such a requirement necessitates the "mapping" of RSVP or other GQOS parameters to WAN technology QOS interfaces.

Layer 2, however, is where GQOS technology interacts most with the WAN's underlying signaling, since it is in Layer 2 where existing WAN technologies implement their own native QOS components. L2 signaling, in GQOS terms, takes GQOS information, such as parameters that are carried in RSVP messages to or through each network node between end devices, and maps that GQOS information to native WAN technology QOS interfaces.


Subnet Bandwidth Manager

[This is preliminary documentation and subject to change.]

The Subnet Bandwidth Manager (SBM) is the GQOS component that provides resource management and policy-based admission control for QOS-aware applications that use local 802 subnets (Ethernet, for example). The SBM is based on an IETF-draft that defines SBM functionality and its general implementation.

SBM is implemented in Windows NT 5.0 through the Admission Control Service (ACS). ACS is a Windows NT service that resides on a Windows NT 5.0 server.


Policy-Driven GQOS Components

[This is preliminary documentation and subject to change.]

Admission Control Service (ACS)
A Windows NT service, residing on a Windows NT server machine, that inserts itself into the RSVP message path to enforce Windows NT Directory Service-based network admission services for QOS-enabled clients.
Local Policy Module (LPM)
A Microsoft-provided service that provides network resource access decisions, based on policies configured via the ACS, for the Subnet Bandwidth Manager (SBM) component. The LPM interacts over the network with the client-based Policy Element
Policy Element (PE)
A policy component that resides on the client and provides authentication information to facilitate reservation requests. The PE resides on the client and communicates policy information via a kerberos ticket to the LPM residing on the local ACS. The PE is a DLL provided by Microsoft to facilitate turnkey implementation of GQOS.
RSVP
Carries policy objects (data) between end nodes and the ACS/SBM. Also carries rejections to admission requests back to the requesting node.
Local Policy Module API (LPM API)
The programmatic interface for the LPM component.
Policy Element API (PE API)
The programmatic interface for the PE component.
Third Party API (LDAP)
The programmatic interface that exposes policy information stored in the Windows NT Active Directory. This Third Party "API" uses the Lightweight Directory Access Protocol (LDAP), and provides a specification by which acquisition of policy information from the Windows NT Active Directory can be achieved..

For a figure that shows where these components fit into the end-to-end GQOS-enabled network picture, see GQOS Documentation Structure.


Admission Control Service

[This is preliminary documentation and subject to change.]

Admission Control Service (ACS), is a GQOS component that regulates subnet usage for QOS-enabled applications. The ACS exerts its authority over QOS-aware applications or clients by placing itself within the RSVP message path. With this placement, ACS effectively intercepts RSVP PATH and RESV messages and passes the messages' user information down to Local Policy Modules (LPMs) for authentication.

ACS regulation is based on available network resources and on administratively configurable information on users, applications, or group policy. ACS is implemented as a Windows NT service on a server running Windows NT.

Local Policy Modules (LPMs) fall within the fold of ACS functionality, and can be considered an integral part of the ACS. With the default LPM, user information is compared with Windows NT Active Directory policy information for authentication.

Another ACS component, the Policy Control Module (PCM), actually mediates the interaction between the ACS and LPMs. If there are multiple residential LPMs, the PCM will send user information to each LPM and gather all responses, then perform logical checks on the information, aggregate it, and return one response to the ACS.

If network resources are available and if authentication succeeds, the RSVP message and its policy information is sent to the next (or previous, depending on whether it is a PATH or RESV message) hop. In this way, ACS acts as the logical gatekeeper for RSVP message propagation across the network: No further RSVP processing will occur (since the RSVP won't be passed to the next appropriate hop), outside of an RSVP error message in either of the following cases:

  • If local segment resources aren't available to provide the requested level of QOS (the SBM functionality of the ACS).
  • If the sender or receiver doesn't have appropriate policy permission to transmit data at the requested rate.

This provides twofold service. It keeps unnecessary traffic from traversing the network by keeping lame-duck RSVP messages from running across the network, and it preserves processing resources for routers and WAN Network Interface Cards (WANICs) since they will not have to handle such RSVP messages. Note that any node that declines requests based on policy failure, however, will return and RSVP error message to the sender, indicating such failure.

Though ACS is a GQOS component, its services include other GQOS components, such as the Subnet Bandwidth Manager (SBM) and its LPM interface.


Policy Element

[This is preliminary documentation and subject to change.]

The Policy Element (PE) component is the Microsoft-provided policy interface for Windows clients. The PE provides policy information that is incorporated in network resource reservation requests, which in turn get sent out onto the network. This policy information is intercepted by the Admission Control Service (ACS) (which includes SBM functionality as part of its fundamental service suite). The ACS services such requests by checking whether the requesting client has authorization to use network resources on the local subnet. If successful, policy information is forwarded on to the next network node for subsequent policy checking, and such activity continues toward the intended receiver, along the data path of network nodes, until the request is rejected or the intended receiver (the node with which the sending client wishes to communicate) is reached.


Policy Element API

[This is preliminary documentation and subject to change.]

The Policy Element (PE) API is a programmatic interface for the PE component, providing the ability to use PE services outside of the Admission Control Service.


Third Party API (LDAP)

[This is preliminary documentation and subject to change.]

The Third Party "API" in a Lightweight Directory Access Protocol (LDAP) interface for accessing policy-based admission information stored in the Windows NT Active Directory. Its definition requires a quick treatment of the process of gaining such information.

The Admission Control Service (ACS) is the GQOS component that provides a policy-based means of regulating and managing network resources associated with 802 (shared media) LANs (the ACS service encompasses SBM functionality within its base service). The means by which network resources are regulated is through permission and admission policies; the ACS interfaces indirectly with LPMs in order to gain approval or rejection of a node's requested network resources. LPMs can be considered the go-betweens for ACS admission policy queries and the user's policy store (presumably some sort of authentication/policy store, perhaps a centralized database of enterprise-wide authentication information). In the default LPM that ships with Windows NT 5.0, the LPM is implemented through a DLL called MSIDPE.DLL, which provides a policy interface to Windows NT's centralized database of enterprise-wide information, the Active Directory. Thus, in the ACS component model, policy information is provided through MSIDPE.DLL, or as it is referred to throughout this documentation, the LPM component. ACS policy decisions, regarding access to network device resources, are realized through the LPM component's access to Windows NT Active Directory policy stores.

In order for Active Directory policy information to be made available to other network devices–devices such as routers, WAN interfaces, or switches that might be interested in regulating resource admission based on the Active Directory's configurable policy information–a programmatic interface to policy information stores in the Windows NT Active Directory was necessary. The interface that exposes Windows NT Active Directory policy information is accessible through LDAP, and is called the Third Party API.


Local Policy Module

[This is preliminary documentation and subject to change.]

The Local Policy Module (LPM) is a GQOS component responsible for retrieving and returning policy information used within the Admission Control Service (ACS). A default Windows NT LPM provides an interface to policy information that is configured and stored in the Windows NT 5.0 Active Directory. LPM is a generic term used to denote the implementation of a "courier service" used to provide the ACS with a means of retrieving policy information from a given policy store. LPMs will generally be implemented as a DLL.

LPMs provided for an ACS server or service must have a corresponding component (a DLL) that resides on the client. LPMs are thus implemented on the end node and the ACS server; this is a necessary logical configuration, as end-node generated user information, carried by RSVP to the ACS (which then gets forwarded down to the LPM), must be provided in a format that the ACS's LPM is expecting and can process.

It is important to note the difference between IETF draft technologies and Microsoft's implementation of such technologies. Subnet Bandwidth Manager (SBM), for example, is a technology begotten from an IETF draft proposal for regulating access to 802 subnets (IETF draft-yavatkar-sbm-ethernet-03.txt). ACS is a Windows NT 5.0 service (and a GQOS component) that incorporates SBM technology within its fold to incorporate regulation of access to 802 subnets in accordance with policy control.

In the SBM IETF draft, the implementation and integration of policy regulation within the SBM technology is extensively discussed and outlined, but is necessarily unspecific; with ACS and the LPM(s) that couriers policy information from a centralized policy store (the Active Directory when using the GQOS PE component), the generalized IETF draft finds specific implementation within Windows NT 5.0.


Local Policy Module API

[This is preliminary documentation and subject to change.]

The LPM API is the programmatic interface by which LPMs communicate and interact with the Admission Control Service (ACS). The LPM API also specifies how LPMs are registered and initialized within the constructs of the ACS.

Such interaction is actually regulated by an abstraction service called the Policy Control Module (PCM). Because it is possible to have multiple LPMs, the PCM filters and aggregates information. For example, the PCM takes information returned from multiple LPMs (if multiple LPMs are installed on the system) and performs logical policy comparisons on their results, then returns one set of information to the ACS.

The LPM API consists of a handful of functions used to allow its interaction with the ACS. The interaction of an LPM with its corresponding policy store is excluded from this interface; such interfacing would be proprietary to the LPM and the policy store.


RSVP

[This is preliminary documentation and subject to change.]

RSVP (Resource Reservation Protocol) is an IETF-draft networking protocol dedicated to being the facilitator and carrier of 'standardized' Quality of Service information and parameters. RSVP carries generic (industry defined) QOS parameters from end nodes (inclusive) to each QOS-aware network device included in the 'hop path' between RSVP session members. In a sentence, RSVP is a means by which end nodes, and network devices, can communicate and negotiate QOS parameters and network usage admission.

RSVP is a multi-faceted protocol; it is active and central to application-driven, network-driven, and policy driven GQOS activities, in that it is the 'container' by which GQOS parameters and information is sent across the network. RSVP has its own objects which can be filled or interrogated to specify or determine the requested QOS parameters that are either requested by the application, required of the network device, or applied for by the user. Since RSVP has its own clearly-defined objects, the implementation of RSVP within Windows NT 5.0 requires GQOS parameters to be 'mapped' into (or on the receiving end of RSVP messages, derived from) RSVP objects. Such mapping (i.e., translation of RSVP into natively understood information) will occur on each QOS-aware network device that RSVP interacts with, allowing, in the end, a protocol that can carry and share industry standard QOS information to any device interested in participation in QOS activities.

From an application-driven perspective, RSVP is the means by which an application's requests are transported through the network (a container, though one with specifically defined compartments). Calls to the GQOS API provide information to the GQOS SP, which then maps such information into pre-defined RSVP objects for transmission across the network.

From a network-driven perspective, RSVP provides network devices a predictable and understandable set of information, from which resource availability-based (and/or policy-based) decisions on whether to offer bandwidth reservation can be made.

From a policy-driven perspective, RSVP provides the necessary user information within industry standard RSVP objects (much like a set of containers, each of which is pre-sized based on its clearly marked contents), that facilitate the exchange of user identity and admission requests.

Although RSVP can be considered responsible for the bulk of GQOS interaction among end-nodes, it is possible to achieve QOS without its inclusion, such as by using Traffic Control facilities available with GQOS.


GQOS Reference

[This is preliminary documentation and subject to change.]

This section describes the following GQOS programming elements:

  • GQOS Functions
  • GQOS Structures
  • GQOS Objects


GQOS Functions

[This is preliminary documentation and subject to change.]

This section contains an alphabetic list of GQOS functions.

  • WPUGetQOSTemplate
  • WSAGetQOSByName
  • WSCInstallQOSTemplate
  • WSCRemoveQOSTemplate
  • WSPGetQOSByName


WPUGetQOSTemplate

[This is preliminary documentation and subject to change.]

The GQOS WPUGetQOSTemplate function retrieves a GQOS template for a particular service provider.

INT
WPUGetQOSTemplate(
  IN  const LPGUID lpProviderId,
  IN  LPWSABUF lpQOSName,
  OUT LPQOS lpQOS
);

Parameters

lpProviderId
[in] Pointer to a provider-selected, globally unique identifier (GUID).
lpQOSName
[in] Specifies the QOS template name.
lpQOS
[in] Pointer to a QUALITYOFSERVICE structure.

Return Values

If WPUGetQOSTemplate succeeds, the return value is zero. If the function fails, the return value is SOCKET_ERROR. For extended error information, call WSAGetLastError.

Remarks

The WPUGetQOSTemplate function retrieves a GQOS name template containing the associated QUALITYOFSERVICE structure. If lpProviderId is NULL, WPUGetQOSTemplate attempts to find the GQOS name template in the "global" list of QOS names. Otherwise, WPUGetQOSTemplate searches the template list specific to the service provider indicated by lpProviderId.

The lpQOS parameter can include a ProviderSpecific buffer for retrieval with the basic QUALITYOFSERVICE structure. In this case, the ProviderSpecific buffer must be large enough to hold the provider-specific information stored in the template; otherwise WPUGetQOSTemplate returns WSAENOBUFS.

Error Codes

WSAEFAULT | The lpQOS or lpQOSName argument is not a valid part of the user address space.
WSAEINVAL | The specified lpProviderId is invalid or the lpQOS template is invalid.
WSA_NODATA | The specified GQOS name could not be found.
WSAENOBUFS | The provider-specific buffer is too small.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in qosname.h.

See Also

QUALITYOFSERVICE, WSAGetQOSByName, WSCInstallQOSTemplate, WSCRemoveQOSTemplate


WSAGetQOSByName

[This is preliminary documentation and subject to change.]

The GQOS WSAGetQOSByName function initializes a QUALITYOFSERVICE structure based on a named template, or retrieves an enumeration of the available template names.

BOOL WSAAPI
  WSAGetQOSByName(
  IN  SOCKET s,
  IN  OUT LPWSABUF lpQOSName,
  OUT LPQOS lpQOS
);

Parameters

s
[in] Descriptor identifying a socket.
lpQOSName
[in out] Specifies the QOS template name, or supplies a buffer to retrieve an enumeration of available template names.
lpQOS
[out] Pointer to the QUALITYOFSERVICE structure to be filled.

Return Values

If WSAGetQOSByName succeeds, the return value is TRUE. If the function fails, the return value is FALSE. For extended error information, call WSAGetLastError.

The algorithm that WSAGetQOSByName applies in its search for a template's name match is:

  1. The socket's service provider checks for a provider-specific template with a matching name—a template installed specifically for the socket's service provider—with a name that matches the service provider's name.
  2. If this fails, the service provider checks its internal table of GQOS templates (if it has such a table).
  3. If this fails, the service provider checks for a list of global GQOS templates.
  4. If any one of the above succeeds, the service provider has the option of modifying the GQOS template before returning it to Windows Sockets.
  5. Otherwise WSAGetQOSByName returns FALSE, and WSAGetLastError returns WSA_NODATA to indicate an invalid name.

Remarks

Applications can use WSAGetQOSByName to initialize a QUALITYOFSERVICE structure with a prescribed set of known values appropriate for a particular service class or media type. These known values are stored in a template, and the template is referenced by a well-known name; for example, if the service provider's .dll is named ipphone.dll, the template may be referenced by the name IPPHONE. Applications can retrieve these values by setting the buf member of WSABUF, indicated by lpQOSName, to point to a string of nonzero length specifying a template name. When doing so, lpQOSName is an in parameter only and results are returned through lpQOS.

This function can also be used to retrieve an enumeration of available template names. This is done by setting the buf member of WSABUF, indicated by lpQOSName, to a zero-length, null-terminated string. The buffer indicated by buf is then overwritten with a sequence of as many null-terminated template names as are available—up to the number of bytes available in buf, as provided by the len member of WSABUF indicated by lpQOSName. The list of names itself is terminated by a zero-length name. When WSAGetQOSByName is used to retrieve template names, the lpQOS parameter is ignored.

If two templates have the same name, with one template being specific to the service provider and the other being global, they will appear in the list only once.

Error Codes

WSANOTINITIALISED | A successful call to WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpQOSName or lpQOS arguments are not a valid part of the user address space.
WSAENOBUFS | The buffer length for lpQOS is too small.
WSA_NODATA | The specified QOS template name is invalid.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Use ws2_32.lib.

See Also

QUALITYOFSERVICE, WSAAccept, WSABUF, WSAConnect, WSAIoctl, WSAStartup


WSCInstallQOSTemplate

[This is preliminary documentation and subject to change.]

The GQOS WSCInstallQOSTemplate function installs a GQOS template, based on a GQOS name. This QUALITYOFSERVICE structure (and thus its GQOS settings) can be retrieved by calling the WSPGetQOSByName function, and passing in its associated GQOS name. Note that the caller of this function must have administrative privileges.

BOOL
WSCInstallQOSTemplate(
  IN  const LPGUID lpProviderId,
  IN  LPWSABUF lpQOSName,
  IN  LPQOS lpQOS
);

Parameters

lpProviderId
[in] Pointer to a provider-selected, globally unique identifier (GUID).
lpQOSName
[in] Specifies the GQOS template name.
lpQOS
[in] Pointer to a QUALITYOFSERVICE structure.

Return Values

If WSCInstallQOSTemplate succeeds, the return value is TRUE. If the function fails, the return value is FALSE. For extended error information, call WSAGetLastError.

Remarks

The WSCInstallQOSTemplate function installs a GQOS name template containing the specified and subsequently associated QUALITYOFSERVICE structure, or replaces settings of an existing template. Values are stored in nonvolatile storage, so subsequent calls to WSAGetQOSByName, passing the same lpQOSName, return the QUALITYOFSERVICE structure. If lpProviderId is set to NULL, the installed GQOS name template applies across all service providers; otherwise the GQOS name template applies only to the provider indicated by the lpProviderId parameter.

Windows Sockets 2 includes a base set of GQOS templates. You can override and replace any of these GQOS templates, or change an existing GQOS template, by simply installing a new template with the existing name. You do not need to delete an existing template before replacing or modifying it; the base set of GQOS name templates included in Windows Sockets 2 cannot be deleted. However, templates added subsequently, perhaps by other service providers, can be deleted.

The lpQOS parameter, which points to a QUALITYOFSERVICE structure, can include a ProviderSpecific buffer that will be stored with the basic QUALITYOFSERVICE structure, and returned in subsequent WSAGetQOSByName calls.

Providing the ProviderSpecific buffer, even if lpProviderId is set to NULL, can be used to install global name templates that include provider-specific information. Note that this practice may lead the service provider to ignore the ProviderSpecific buffer if the service provider does not recognize its contents. The recommended use of WSCInstallQOSTemplate is to include a ProviderSpecific buffer only if the name template is being installed against a particular service provider, as implemented when lpProviderId is not NULL.

Error Codes

WSAEINVAL | The specified QOS template name or Provider ID is invalid, or the contents of the template structure is invalid or incomplete.
WSEFAULT | One or more of the arguments is not a valid part of the user address space.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in qosname.h.

See Also

QUALITYOFSERVICE, WPUGetQOSTemplate, WSAGetQOSByName, WSCRemoveQOSTemplate


WSCRemoveQOSTemplate

[This is preliminary documentation and subject to change.]

The GQOS WSCRemoveQOSTemplate function removes a GQOS template. Note that the caller of this function must have administrative privileges.

BOOL
WSCRemoveQOSTemplate(
  IN  const LPGUID lpProviderId,
  IN  LPWSABUF lpQOSName,
);

Parameters

lpProviderId
[in] Pointer to a provider-selected, globally unique identifier (GUID).
lpQOSName
[in] Specifies the GQOS template name.

Return Values

If WSCRemoveQOSTemplate succeeds, the return value is TRUE. If the function fails, the return value is FALSE. For extended error information, call WSAGetLastError.

Remarks

The WSCRemoveQOSTemplate function deletes a GQOS template previously installed with WSCInstallQOSTemplate. If lpProviderId is NULL, WSCRemoveQOSTemplate attempts to find and delete a GQOS template from the "global" list of GQOS names. Otherwise, WSCRemoveQOSTemplate attempts to find and delete a GQOS template specific to the service provider associated with lpProviderId. Windows Sockets 2 includes a base set of GQOS name templates that cannot be deleted. The WSAEINVAL error code will be returned if such an attempt is made.

Error Codes

WSAEINVAL | The specified QOS template name is invalid
WSA_NODATA | The specified QOS template could not be found.
WSEFAULT | One or more of the arguments is not a valid part of the user address space.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in qosname.h.

See Also

WPUGetQOSTemplate, WSAGetQOSByName, WSCInstallQOSTemplate


WSPGetQOSByName

[This is preliminary documentation and subject to change.]

The GQOS WSPGetQOSByName function initializes a QUALITYOFSERVICE structure based on a named template, or retrieves an enumeration of the available template names.

BOOL WSAAPI
  WSAGetQOSByName(
  IN  SOCKET s,
  IN  OUT LPWSABUF lpQOSName,
  OUT LPQOS lpQOS
  OUT LPINT lpErrno
);

Parameters

s
[in] Descriptor identifying a socket.
lpQOSName
[in out] Specifies the QOS template name, or supplies a buffer to retrieve an enumeration of available template names.
lpQOS
[out] Pointer to the QUALITYOFSERVICE structure to be filled.
lpErrno
[out] Pointer to the error code.

Return Values

If WSPGetQOSByName succeeds, the return value is TRUE. If the function fails, the return value is FALSE. Error information is available in lpErrno.

The algorithm that WSPGetQOSByName applies in its search for a template's name match is:

  1. The service provider checks for a provider-specific template by calling WPUGetQOSTemplate, using the service provider's globally unique identifier (GUID) and QOS name as search criteria.
  2. If this fails, the service provider checks its internal table of GQOS templates (if it has such a table).
  3. If this fails, the service provider calls WPUGetQOSTemplate again, using the same QOS name, but this uses NULL for the GUID to facilitate a query of the global list of QOS names.
  4. If any one of the above succeeds, the service provider has the option of modifying the GQOS template before returning it to Windows Sockets.
  5. Otherwise, WSPGetQOSByName returns FALSE, and lpErrno is set to WSA_NODATA.

Remarks

Clients may use this function to initialize a QUALITYOFSERVICE structure with a prescribed set of known values appropriate for a particular service class or media type. These known values are stored in a template, and the template is referenced by a well-known name. Applications may retrieve these values by setting the buf member of WSABUF, indicated by lpQOSName, to point to a Unicode string of nonzero length specifying a template name. When doing so, lpQOSName is an in parameter only, and results are returned through lpQOS.

This function may also be used to retrieve an enumeration of available template names. This is done by setting the buf member of WSABUF, indicated by lpQOSName, to a zero-length, null-terminated Unicode string. The buffer indicated by buf is then overwritten with a sequence of as many null-terminated Unicode template names as are available—up to the number of bytes available in buf, as provided by the len member of WSABUF indicated by lpQOSName. The list of names itself is terminated by a zero-length Unicode name string. When WSPGetQOSByName is used to retrieve template names, the lpQOS parameter is ignored.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpQOSName or lpQOS arguments are not a valid part of the user address space.
WSAENOBUFS | The buffer length for lpQOS is too small.
WSA_NODATA | The specified QOS template name is invalid.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

QUALITYOFSERVICE, WPUGetQOSTemplate, WSABUF, WSCInstallQOSTemplate, WSCRemoveQOSTemplate


GQOS Structures

[This is preliminary documentation and subject to change.]

This section describes the following GQOS structures:

  • FLOWSPEC
  • QUALITYOFSERVICE


FLOWSPEC

[This is preliminary documentation and subject to change.]

The FLOWSPEC structure provides quality of service parameters to the GQOS SP. This allows GQOS-aware applications to invoke, modify, or remove quality of service settings for a given flow.

typedef struct _flowspec {
    uint32        TokenRate;            /* In Bytes/sec            */
    uint32        TokenBucketSize;      /* In Bytes                */
    uint32        PeakBandwidth;        /* In Bytes/sec            */
    uint32        Latency;              /* In microseconds         */
    uint32        DelayVariation;       /* In microseconds         */
    SERVICETYPE   ServiceType;          /* Guaranteed, Predictive, */
                                        /*   Best Effort, etc.     */
   uint32         MaxSduSize            /* In Bytes                */
   uint32         MinimumPolicedSize    /* In Bytes                */
} FLOWSPEC, *PFLOWSPEC,  FAR * LPFLOWSPEC;

Members

TokenRate
Specifies the permitted rate at which data can be transmitted over the life of the flow. TokenRate is similar to other token bucket models seen in such WAN technologies as Frame Relay, in which the token is analogous to a credit. If such tokens are not used immediately, they accrue to allow data transmission up to a certain periodic limit (PeakBandwidth, in the case of GQOS). Accrual of credits is limited, however, to a specified amount (TokenBucketSize). Limiting total credits (tokens) avoids situations where, for example, flows that are inactive for some time flood the available bandwidth with their large amount of accrued tokens. Because flows may accrue transmission credits over time (at their TokenRate value) only up to the maximum of their TokenBucketSize, and because they are limited in "burst transmissions" to their PeakBandwidth, traffic control and network-device resource integrity are maintained. Traffic control is maintained because flows cannot send too much data at once, and network-device resource integrity is maintained because such devices are spared from high traffic bursts.

With this model, applications can transmit data only when sufficient credits are available. If sufficient credit amounts are not available, the application must either wait or discard the traffic (based on the value of QOS_OBJECT_SD_MODE). Therefore it is important that applications base their TokenRate requests on reasonable expectations for transmission requirements. For example, in video applications the TokenRate is typically set to the average bit rate peak to peak.

If the TokenRate member is set to -1, limits on the transmission rate (the token bucket model) will not be put into effect. TokenRate is expressed in bytes per second.

TokenBucketSize
The maximum amount of credits a given direction of a flow can accrue, regardless of time. In video applications, TokenBucketSize will likely be the largest average frame size. In constant rate applications, TokenBucketSize should be set to allow for small variations. TokenBucketSize is expressed in bytes.
PeakBandwidth
The upper limit on time-based transmission permission for a given flow, sometimes considered a burst limit. PeakBandwidth restricts flows that may have accrued a significant amount of transmission credits, or tokens from overburdening network resources with one-time or cyclical data bursts, by enforcing a per-second data transmission ceiling. Some intermediate systems can take advantage of this information, resulting in more efficient resource allocation. PeakBandwidth is expressed in bytes per second.
Latency
Maximum acceptable delay between transmission of a bit by the sender and its receipt by one or more intended receivers. The precise interpretation of this number depends on the level of guarantee specified in the QOS request. Latency is expressed in microseconds.
DelayVariation
Difference between the maximum and minimum possible delay a packet will experience. Applications use DelayVariation to determine the amount of buffer space needed at the receiving end of the flow, in order to restore the original data transmission pattern. DelayVariation is expressed in microseconds.
ServiceType
Specifies the level of service to negotiate for the flow. This member can be one of the following defined service types.
Value | Meaning
SERVICETYPE_NOTRAFFIC | Indicates that no traffic will be transmitted in the specified direction. On duplex capable media, this value signals underlying software to set up unidirectional connections only.
SERVICETYPE_BESTEFFORT | Specifies that GQOS should use FLOWSPEC as a service quality guideline, and makes reasonable efforts to maintain the level of service requested, without making any guarantees on packet delivery.
SERVICETYPE_CONTROLLEDLOAD Provides an end-to-end quality of service that closely approximates transmission quality provided to by best-effort service, as expected under unloaded conditions from the associated network components along the data path.

Applications that use SERVICETYPE_CONTROLLEDLOAD may therefore assume the following:

  • The network will deliver a very high percentage of transmitted packets to their intended receivers; in other words, packet loss will closely approximate the basic packet error rate of the transmission medium.
  • Transmission delay for a very high percentage of the delivered packets will not greatly exceed the minimum transit delay experienced by any successfully delivered packet.

SERVICETYPE_GUARANTEED | Initiates a queuing algorithm within the service provider (such as GQOS on any Windows NT client) that isolates a given flow from the effects of other flows (as much as possible). This isolation guarantees the ability to transmit data at TokenRate for the duration of the connection; however, if the corresponding end-node transmits data faster than TokenRate, the network may delay or discard the excess traffic. If TokenRate is not exceeded over time, Latency is also guaranteed. SERVICETYPE_GUARANTEED is designed for applications that may require a deterministic quality of service but would not benefit from better service (such as real-time control systems).

Other defined ServiceType values provide information that can be useful for determining the result of errors or getting information about network service availability. Note that nodes throughout the network use and pass information through what becomes the FLOWSPEC, allowing for such communication to occur between network devices such as routers or WAN adapters, and end nodes, either due to timeouts or due to intentional use of PATH and RESV messages. Such ServiceType values include the following:
Value | Meaning
SERVICETYPE_NETWORK UNAVAILABLE | Used by a service provider to indicate a loss of service in the sending or receiving direction.
SERVICETYPE_GENERAL_INFORMATION | Specifies that all service types are supported for a flow.
SERVICETYPE_NOCHANGE | Indicates that the quality of service in the transmission using this ServiceType value is not changed. SERVICETYPE_NOCHANGE can be used when requesting a change in the quality of service for one direction only, or when requesting a change only within the ProviderSpecific parameters of a QOS specification, and not in the SendingFlowspec or ReceivingFlowspec.
SERVICETYPE_IMMEDIATE_TRAFFIC_CONTROL | Can be combined, using bit-wise OR, with one of the other defined ServiceType values to request the service provider to activate traffic control concurrently with provision of the FLOWSPEC, as opposed to sending with best-effort until RESV messages are received.

MaxSduSize
Specifies the maximum packet size permitted or used in the traffic flow. MaxSduSize is expressed in bytes.
MinimumPolicedSize
Specifies the minimum packet size for which the requested quality of service will be provided. MinimumPolicedSize is expressed in bytes.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in rsvp.h.


QUALITYOFSERVICE

[This is preliminary documentation and subject to change.]

The QUALITYOFSERVICE structure provides the means by which GQOS-enabled applications can specify quality of service parameters for sent and received traffic on a particular flow.

typedef struct _QualityOfService {
    FLOWSPEC    SendingFlowspec;       /* The flowspec for data  */
                                       /*   sending              */
    FLOWSPEC    ReceivingFlowspec;     /* The flowspec for data  */
                                       /*   receiving            */
    WSABUF      ProviderSpecific;      /* Additional provider-   */
                                       /*   specific parameters  */
} QOS, FAR * LPQOS;

Members

SendingFlowspec
Specifies QOS parameters for the sending direction of a particular flow. SendingFlowspec is sent in the form of a FLOWSPEC structure.
ReceivingFlowspec
Specifies QOS parameters for the receiving direction of a particular flow. ReceivingFlowspec is sent in the form of a FLOWSPEC structure.
ProviderSpecific
Pointer to a structure of type WSABUF that can provide additional provider-specific QOS parameters to the GQOSSP for a given flow.

Remarks

Most applications can fulfill their quality of service requirements without using the ProviderSpecific buffer. However, if the application must provide information not available with standard GQOS parameters, the ProviderSpecific buffer allows the application to provide additional parameters for RSVP and/or Traffic Control.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in rsvp.h.

See Also

FLOWSPEC, ProviderSpecific


GQOS Objects

[This is preliminary documentation and subject to change.]

Applications that require specific or granular quality of service control, beyond what is available in the GQOS API, can use GQOS objects. GQOS objects implement Windows NT-specific functionality, such as traffic control-related objects, as well as industry-wide functionality such as RSVP-related objects. GQOS objects are implemented through the ProviderSpecific buffer in the FLOWSPEC structure, which is a member of the QUALITYOFSERVICE structure.

GQOS objects follow a stringent structure. GQOS objects always include an information header that specifies the type and length of the GQOS object to which it is attached, followed by the object itself.

This section describes the following:

The ProviderSpecific Buffer

QOS_OBJECT_HDR

QOS_OBJECT_PRIORITY

QOS_OBJECT_SD_MODE

RSVP_ADSPEC

RSVP_RESERVE_INFO

RSVP_STATUS_INFO


The ProviderSpecific Buffer

[This is preliminary documentation and subject to change.]

The ProviderSpecific buffer provides applications with special QOS needs a mechanism to achieve their required quality of service. ProviderSpecific is of type WSABUF as defined by Windows Sockets 2 and is a member of the QUALITYOFSERVICE structure.

The standard mechanisms by which GQOS provides applications quality of service capabilities will fulfill the requirements for the majority of applications. In some situations, however, service quality parameters not available with standard GQOS mechanisms may need to be implemented. The ProviderSpecific buffer interface is provided for those situations.

The ProviderSpecific buffer specifically includes a length field and a pointer to a buffer, which may contain one or more (GQOS) objects. The format of each object is as follows:

  • Each object includes a type field, which specifically identifies the object, followed by:
  • A length field, which contains the length of the object exclusive of the header, followed by:
  • The object data itself.

See GQOS Objects for more information.


QOS_OBJECT_HDR

[This is preliminary documentation and subject to change.]

The GQOS object QOS_OBJECT_HDR is attached to each GQOS object. It specifies the object type and its length.

Struct {
ULONG      ObjectType;
ULONG      ObjectLength;
} QOS_OBJECT_HDR;

Members

ObjectType
Specifies the type of object to which QOS_OBJECT_HDR is attached.
ObjectLength
Specifies the length of the attached object, exclusive of QOS_OBJECT_HDR.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in traffic.h.


QOS_OBJECT_PRIORITY

[This is preliminary documentation and subject to change.]

The GQOS object QOS_OBJECT_PRIORITY specifies the absolute priority of a given flow.

struct {
QOS_OBJECT_HDR     ObjectHdr;
UCHAR              SendPriority;      /* sending priority      */
UCHAR              SendFlags;         /* currently not defined */
UCHAR              ReceivePriority;   /* currently not used    */
}

Members

ObjectHdr
The GQOS object QOS_OBJECT_HDR.
SendPriority
Applies absolute priority to a flow. Priority values range from 0 to 7. Default priority value for any flow is 3.
SendFlags
Reserved for future use.
ReceivePriority
Currently not used.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in traffic.h.

See Also

FLOWSPEC, QOS_OBJECT_HDR, The ProviderSpecific Buffer


QOS_OBJECT_SD_MODE

[This is preliminary documentation and subject to change.]

The GQOS object QOS_OBJECT_SD_MODE defines the behavior of Traffic Control's Packet Shaper component.

Struct {
QOS_OBJECT_HDR     ObjectHdr;
ULONG              ShapeDiscardMode;
} QOS_SD_MODE

Members

ObjectHdr
The GQOS object QOS_OBJECT_HDR.
ShapeDiscardMode
Specifies the requested behavior of the Packet Shaper. Note that there are elements of packet handling within these predefined behaviors that depend on the flow's settings as specified within FLOWSPEC.
Value | Meaning
TC_NONCONF_BORROW | Instructs the Packet Shaper to "borrow" remaining available resources after all higher priority flows have been serviced. If the TokenRate member of FLOWSPEC is specified for this flow, packets that exceed the value of TokenRate will have their priority demoted to less than SERVICETYPE_BESTEFFORT, as defined in the ServiceType member of the FLOWSPEC structure.
TC_NONCONF_SHAPE | Instructs the Packet Shaper to retain packets until network resources are available to the flow in sufficient quantity to make such packets conforming. (For example, a 100K packet will be retained in the Packet Shaper until 100K worth of credit is accrued for the flow, allowing the packet to be transmitted as conforming). Note that TokenRate must be specified if using TC_NONCONF_SHAPE.
TC_NONCONF_DISCARD | Instructs the Packet Shaper to discard all nonconforming packets. TC_NONCONF_DISCARD should be used with care.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in traffic.h.


RSVP_ADSPEC

[This is preliminary documentation and subject to change.]

The GQOS object RSVP_ADSPEC provides a means by which information describing network devices along the data path between sender and receiver, pertaining to RSVP functionality and available services, is apprehended.

typedef struct _RSVP_ADSPEC  {
   QOS_OBJECT_HDR     ObjectHdr;        /* Object Hdr              */
   AD_GENERAL_PARAMS  GeneralParams;    /* contains the general    */
                                        /*   characterization      */
                                        /*   parameters            */
   ULONG              NumberOfServices; /* count of the number     */
                                        /*   of services           */
   CONTROL_SERVICE    Services[1];      /* a list of the services  */
                                        /*   supported/requested   */
} RSVP_ADSPEC, *LPRSVP_ADSPEC;

Members

ObjectHdr
The GQOS object QOS_OBJECT_HDR.
GeneralParams
An AD_GENERAL_PARAMS structure that provides general characterization parameters for the flow. Information includes RSVP-enabled hop count, bandwidth and latency estimates, and the path's MTU.
NumberOfServices
Provides a count of the number of services available. (See the following member for more information.)
Services
A CONTROL_SERVICE array, its element count based on NumberOfServices, that provides information about the services available along the data path between the sender and receiver of a given flow.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in traffic.h.


RSVP_RESERVE_INFO

[This is preliminary documentation and subject to change.]

The GQOS object RSVP_RESERVE_INFO, through the ProviderSpecific buffer, allows RSVP behavior for a given flow to be specified or modified at a granular level, and allows default RSVP style settings for a flow to be overridden. Although RSVP_RESERVE_INFO is technically a structure, its use within GQOS technology, and especially its required inclusion of the QOS_OBJECT_HDR as its first member, define it as a GQOS object.

typedef struct _RSVP_RESERVE_INFO {
   QOS_OBJECT_HDR    ObjectHdr;         /* type and length of     */
                                        /*   this object          */
   ULONG             Style;             /* RSVP Style (FF,WF,SE)  */
   ULONG             ConfirmRequest;    /* Non Zero for Confirm   */
                                        /*   Request(receive only)*/
   ULONG             NumPolicyElement;  /* Number of policy       */
                                        /*   elements             */
   LPRSVP_POLICY     PolicyElementList; /* Points to the set of   */
                                        /*   policy elements      */
   ULONG             NumFlowDesc;       /* Number of FlowDesc     */
   LPFLOWDESCRIPTOR  FlowDescList;      /* Points to the FlowDesc */
                                        /*   list                 */
} RSVP_RESERVE_INFO, *LPRSVP_RESERVE_INFO;

Members

ObjectHdr
The GQOS object QOS_OBJECT_HDR.
Style
Specifies the RSVP reservation style for a given flow, and can be used to replace default reservation styles placed on a particular type of flow. This member can be one of the following values.
Value | Meaning
RSVP_WILDCARD_SYLE | Implements the WF RSVP reservation style. RSVP_WILDCARD_STYLE is the default value for multicast receivers and UDP unicast receivers. Specifying RSVP_WILDCARD_STYLE through RSVP_RESERVE_INFO is useful for overriding the default value (RSVP_FIXED_FILTER_STYLE) applied to connected unicast receivers.
RSVP_FIXED_FILTER_STYLE | Implements the Fixed Filter (FF) RSVP reservation style. RSVP_FIXED_FILTER_STYLE is useful for overriding the default style for multicast receivers or unconnected UDP unicast receivers (RSVP_WILDCARD_STYLE). RSVP_FIXED_FILTER_STYLE may also be used to generate multiple RSVP_FIXED_FILTER_STLYE reservations in instances where only a single RSVP_FIXED_FILTER_STYLE reservation will be generated by default, such as with connected unicast receivers.
RSVP_SHARED_EXPLICIT_STYLE | Implements the Shared Explicit (SE) RSVP reservation style.

ConfirmRequest
Can be used by a receiving application to request notification of its reservation request by setting ConfirmRequest to a nonzero value. Such notification is achieved when RSVP-aware devices in the data path between sender and receiver (or vice-versa) transmit a RESV CONFIRMATION message toward the requesting node. Note that an RSVP node is not required to automatically generate RESV CONFIRMATION messages.
NumPolicyElement
Specifies the number of policy elements.
PolicyElementList
Pointer to the set of policy elements. Optional policy information, as provided in an RSVP_POLICY structure.
NumFlowDesc
Specifies the FLOWDESCRIPTOR count.
FlowDescList
Pointer to the list of FLOWDESCRIPTORs.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in traffic.h.


RSVP_STATUS_INFO

[This is preliminary documentation and subject to change.]

The GQOS object RSVP_STATUS_INFO provides information regarding the status of RSVP for a given flow, including error information. RSVP_STATUS_INFO is useful for storing RSVP-specific status and error information.

typedef struct _RSVP_STATUS_INFO {
   QOS_OBJECT_HDR      ObjectHdr;       /* Object Hdr              */
   ULONG               StatusCode;      /* Error or Status Informa-*/
                                        /*   tion see Winsock2.h   */
   ULONG               ExtendedStatus1; /* Provider specific status*/
                                        /*   extension             */
   ULONG               ExtendedStatus2; /* Provider specific status*/
                                        /*   extension             */
} RSVP_STATUS_INFO, *LPRSVP_STATUS_INFO;

Members

ObjectHdr
The GQOS object QOS_OBJECT_HDR.
StatusCode
Status information. See winsock2.h for more information.
ExtendedStatus1
Mechanism for storing or returning provider-specific status information.
ExtendedStatus2
Additional mechanism for storing or returning provider-specific status information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in traffic.h.


Legal Information

Windows Sockets 2 Application Programming Interface

This is a preliminary document and may be changed substantially prior to final commercial release. This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document. Information in this document is subject to change without notice. The entire risk of the use or the results of the use of this document remains with the user. The names of companies, products, people, characters, and/or data mentioned herein are fictitious and are in no way intended to represent any real individual, company, product, or event, unless otherwise noted. Complying with all applicable copyright laws is the responsibility of the user. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Microsoft Corporation. If, however, your only means of access is electronic, permission to print one copy is hereby granted.

Portions of this document specify and accompany software that is still in development. Some of the information in this documentation may be inaccurate or may not be an accurate representation of the functionality of final documentation or software. Microsoft assumes no responsibility for any damages that might occur directly or indirectly from these inaccuracies.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

©1996-1998 Microsoft Corporation. All rights reserved.

Microsoft, MS, Win32, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

Intel is a registered trademark of Intel Corporation.

All other product and company names mentioned herein are the trademarks of their respective owners.


Welcome To Windows Sockets 2

This document describes the Windows Sockets 2 Application Programming Interface (API). It consists, primarily, of information from the Windows Sockets 2 API specification, but also includes additional information. The information in this document is not presented in exactly the same way as specification.


Using This Document

This document provides the on-line material needed to create a Windows Sockets application for the Windows NT and the Windows 95 operating systems, using the Microsoft implementation of Windows Sockets 2. It is intended as a reference tool and outlines the functions in the Windows Sockets API.

You should be familiar with Win32 programming concepts to make the best use of this document. Thus, you may want to refer to other references that provide a more systematic guide to writing Windows Sockets applications.

Note This documentation is intended for application developers. If you are developing a transport or service provider, see the "Service Provider Documentation" installed with the Platform SDK.


Overview of Windows Sockets 2

Windows Sockets 2 utilizes the sockets paradigm that was first popularized by Berkeley Software Distribution (BSD) UNIX. It was later adapted for Microsoft Windows in the Windows Sockets 1.1.

One of the primary goals of Windows Sockets 2 has been to provide a protocol-independent interface fully capable of supporting the emerging networking capabilities, such as real-time multimedia communications.

Windows Sockets 2 is an interface, not a protocol. As an interface, it is used to discover and utilize the communications capabilities of any number of underlying transport protocols. Because it is not a protocol, it does not in any way affect the "bits on the wire", and does not need to be utilized on both ends of a communications link.

Windows Sockets programming previously centered around TCP/IP. Some of the programming practices that worked with TCP/IP do not work with every protocol. As a result, the Windows Sockets 2 API added new functions where necessary.

Windows Sockets 2 has changed its architecture to provide easier access to multiple transport protocols. Following the Windows Open System Architecture (WOSA) model, Windows Sockets 2 now defines a standard service provider interface (SPI) between the application programming interface (API), with its functions exported from WS2_32.DLL, and the protocol stacks. Consequently, Windows Sockets 2 support is not limited to TCP/IP protocol stacks as is the case for Windows Sockets 1.1. For more information, see Windows Sockets 2 Architecture.

There are new challenges in developing Windows Sockets 2 applications. When sockets only supported TCP/IP, a developer could create an application that supported only two socket types: connectionless and connection-oriented. Connectionless protocols used SOCK_DGRAM sockets and connection-oriented protocols used SOCK_STREAM sockets. Now, these are just two of the many new socket types. Additionally, developers can no longer rely on socket type to describe all the essential attributes of a transport protocol.


Windows Sockets 2 Features

The new Windows Sockets 2 extends functionality in a number of areas.

Windows Sockets 2 Features

Access to protocols other than TCP/IP | Windows Sockets 2 allows an application to use the familiar socket interface to achieve simultaneous access to a number of installed transport protocols.
Overlapped I/O with scatter/gather | Windows Sockets 2 incorporates the overlapped paradigm for socket I/O and incorporates scatter/gather capabilities as well, following the model established in Win32 environments.
Protocol-independent name resolution facilities: | Windows Sockets 2 includes a standardized set of functions for querying and working with the myriad of name resolution domains that exist today (for example DNS, SAP, and X.500).
Protocol-independent multicast and multipoint: | Windows Sockets 2 applications discover what type of multipoint or multicast capabilities a transport provides and use these facilities in a generic manner.
Quality of service | Window Sockets 2 establishes conventions applications use to negotiate required service levels for parameters such as bandwidth and latency. Other QOS-related enhancements include mechanisms for network-specific QOS extensions.
Other frequently requested extensions | Windows Sockets 2 incorporates shared sockets and conditional acceptance; exchange of user data at connection setup/teardown time; and protocol-specific extension mechanisms.


Conventions for New Functions

Windows Sockets 2, with its expanded scope, takes the socket paradigm beyond the original design. As a result, a number of new functions have been added. These have been assigned names that begin with "WSA." In all but a few instances, these new functions are expanded versions of existing functions from BSD sockets.

The new functions are described in the reference section of the document, following the conventions of the Platform SDK. The new functions are also listed in Summary of New Functions.


Microsoft Extensions and Windows Sockets 2

The Windows Sockets 2 specification defines an extension mechanism that exposes advanced transport functionality to application programs. For more information, see Function Extension Mechanism.

The following Microsoft-specific extensions were added to Windows Sockets 1.1. They are also available in Windows Sockets 2.

AcceptEx

GetAcceptExSockaddrs

TransmitFile

WSARecvEx

These functions are not exported from the WS2_32.DLL; they are exported from MSWSOCK.DLL.

An application written to use the Microsoft-specific extensions to Windows Sockets will not run correctly over a Windows Sockets service provider that does not support those extensions.


Socket Handles for Windows Sockets 2

A socket handle can optionally be a file handle In Windows Sockets 2. It is possible to use socket handles with ReadFile, WriteFile, ReadFileEx, WriteFileEx, DuplicateHandle, and other Win32 functions. Not all transport service providers will support this option. For an application to run over the widest possible number of service providers, it should not assume that socket handles are file handles.

Windows Sockets 2 has expanded certain functions used for transferring data between sockets using handles. The functions offer advantages specific to sockets for transferring data and include WSARecv, WSASend, and WSADuplicateSocket.


New Concepts, Additions and Changes for Windows Sockets 2

This section summarizes Windows Sockets 2 and describes the major changes and additions it contains. Windows Sockets 2 differs from Windows Sockets 1.1 in several ways, particularly in the architecture. The new architecture, discussed in Windows Sockets 2 Architecture, provides the foundation for many of the new concepts that have been incorporated into Windows Sockets 2.

An overview of the additions and changes in Windows Sockets 2 follows the discussion of the new architecture.

Many of the functions in Windows Sockets 2 are the same as in the other versions of sockets. However, there are several new functions, which are summarized in Summary of New Functions. For detailed information on how to use a specific function or feature, refer to the Reference section.


Windows Sockets 2 Architecture

A number of Windows Sockets 2 features required a substantial change in the Windows Sockets architecture. The resulting architecture is considerably different from previous versions, but the benefits are numerous. Foremost among these is Simultaneous Access to Multiple Transport Protocols, explained in detail in the following section.

Other features include the adoption of protocol-independent name resolution facilities, provisions for layered protocols and protocol chains, and a different mechanism for Windows Sockets service providers to offer extended, provider-specific functionality.


Simultaneous Access to Multiple Transport Protocols

In order to provide simultaneous access to multiple transport protocols, the architecture has changed for Windows Sockets 2. With Windows Sockets 1.1, the DLL that implements the Windows Sockets interface is supplied by the vendor of the TCP/IP protocol stack. The interface between the Windows Sockets DLL and the underlying stack was both unique and proprietary. Windows Sockets 2 changes the model by defining a standard service provider interface (SPI) between the Windows Sockets DLL and protocol stacks. In this way, multiple stacks from different vendors can be accessed simultaneously from a single Windows Sockets DLL. Furthermore, Windows Sockets 2 support is not limited to TCP/IP protocol stacks as it is in Windows Sockets 1.1.

The Windows Open System Architecture (WOSA) compliant Windows Sockets 2 architecture is illustrated as follows:

Windows Sockets 2 Architecture

With the Windows Sockets 2 architecture, it is not necessary, or desirable, for stack vendors to supply their own implementation of WS2_32.DLL, since a single WS2_32.DLL must work across all stacks. The WS2_32.DLL and compatibility shims should be viewed in the same way as an operating system component.


Backward Compatibility For Windows Sockets 1.1 Applications

Windows Sockets 2 has been made backward compatible with Windows Sockets 1.1 on two levels: source and binary. This maximizes interoperability between Windows Sockets applications of any version and Windows Sockets implementations of any version. It also minimizes problems for users of Windows Sockets applications, network stacks, and service providers. Current Windows Sockets 1.1-compliant applications will run over a Windows Sockets 2 implementation without modification of any kind, as long as at least one TCP/IP service provider is properly installed.

Source Code Compatibility

Source code compatibility in Windows Sockets 2 means, with few exceptions, that all the Windows Sockets 1.1 functions are preserved in Windows Sockets 2. Windows Sockets 1.1 applications that make use of blocking hooks will need to be modified since blocking hooks are no longer supported in Windows Sockets 2. (For more information, see Windows Sockets 1.1 Blocking routines & EINPROGRESS.)

Thus, existing Windows Sockets 1.1 application source code can easily be moved to the Windows Sockets 2 system by including the new header file, WINSOCK2.H, and performing a straightforward relink with the appropriate Windows Sockets 2 libraries. Application developers are encouraged to view this as the first step in a full transition to Windows Sockets 2 because there are numerous ways in which a Windows Sockets 1.1 application can be improved by exploring and using the new functionality in Windows Sockets 2.

Binary Compatibility

A major design goal for Windows Sockets 2 was to enable existing Windows Sockets 1.1 applications to work, unchanged at a binary level, with Windows Sockets 2. Since Windows Sockets 1.1 applications are TCP/IP-based, binary compatibility implies that TCP/IP-based Windows Sockets 2 Transport and Name Resolution Service Providers are present in the Windows Sockets 2 system. In order to enable Windows Sockets 1.1 applications in this scenario, the Windows Sockets 2 system has an additional "shim" component supplied with it: a Version 1.1-compliant WINSOCK.DLL.

Installation guidelines for Windows Sockets 2 ensure there will be no negative impact to existing Windows Sockets-based applications on an end user system by the introduction of any Windows Sockets 2 components.

Windows Sockets 1.1 Compatibility Architecture

Important To obtain information about the underlying TCP/IP stack, Windows Sockets 1.1 applications currently use certain members of the WSAData structure (obtained through a call to WSAStartup). These members include: iMaxSockets, iMaxUdpDg, and lpVendorInfo.

While Windows Sockets 2 applications ignore these values (since they cannot uniformly apply to all available protocol stacks), safe values are supplied to avoid breaking Windows Sockets 1.1 applications.


Making Transport Protocols Available To Windows Sockets

A transport protocol must be properly installed on the system and registered with Windows Sockets to be accessible to an application. The WS2_32.DLL exports a set of functions to facilitate the registration process. This includes creating a new registration and removing an existing one.

When new registrations are created, the caller (that is, the stack vendor's installation script) supplies one or more filled in WSAPROTOCOL_INFO structures containing a complete set of information about the protocol. (See the Welcome To Windows Sockets 2 SPI for information on how this is accomplished.) Any transport stack that is installed this way will be referred to as a Windows Sockets service provider.

The Windows Sockets 2 SDK includes a small Windows applet, SPORDER.EXE, that allows the user to view and modify the order in which service providers are enumerated. By using this SPORDER.EXE, a user can manually establish a particular TCP/IP protocol stack as the default TCP/IP provider if more than one such stack is present.

The SPORDER.EXE applet exports functions from SPORDER.DLL to reorder the service providers. As a result, installation applications can use the interface of SPORDER.DLL to programmatically reorder service providers to suit their needs.


Layered Protocols and Protocol Chains

Windows Sockets 2 incorporates the concept of a layered protocol. A layered protocol is one that implements only higher level communications functions while relying on an underlying transport stack for the actual exchange of data with a remote endpoint. An example of this type of layered protocol is a security layer that adds a protocol to the socket connection process in order to perform authentication and establish an encryption scheme. Such a security protocol generally requires the services of an underlying, reliable transport protocol such as TCP or SPX.

The term base protocol refers to a protocol, such as TCP or SPX, that is fully capable of performing data communications with a remote endpoint. A layered protocol is a protocol that cannot stand alone, while a protocol chain is one or more layered protocols strung together and anchored by a base protocol.

A protocol chain is created by having the layered protocols support the Windows Sockets 2 SPI at both their upper and lower edges. A special WSAPROTOCOL_INFO structure is created that refers to the protocol chain as a whole, and that describes the explicit order in which the layered protocols are joined. This is illustrated in the figure Layered Protocol Architecture. Since only base protocols and protocol chains are directly usable by applications, they are the only ones listed when the installed protocols are enumerated with the WSAEnumProtocols function.

Layered Protocol Architecture


Using Multiple Protocols

An application uses the WSAEnumProtocols function to determine which transport protocols and protocol chains are present, and to obtain information about each as contained in the associated WSAPROTOCOL_INFO structure.

In most instances, there is a single WSAPROTOCOL_INFO structure for each protocol or protocol chain. However, some protocols exhibit multiple behaviors. For example, the SPX protocol is message oriented (that is, the sender's message boundaries are preserved by the network), but the receiving socket can ignore these message boundaries and treat it as a byte stream. Thus, two different WSAPROTOCOL_INFO structure entries could exist for SPX—one for each behavior.

In Windows Sockets 2, several new address family, socket type, and protocol values appear. Windows Sockets 1.1 supported a single address family (AF_INET) comprising a small number of well-known socket types and protocol identifiers. The existing address family, socket type, and protocol identifiers are retained for compatibility reasons, but new transport protocols with new media types are supported.

A Windows Sockets 2 clearinghouse has been established for protocol stack vendors to obtain unique identifiers for new address families, socket types, and protocols. FTP and World Wide Web servers are used to supply current identifier/value mappings, and email is used to request allocation of new ones. This is the World Wide Web URL for the Windows Sockets 2 Identifier Clearinghouse:

http://www.stardust.com/wsresource/winsock2/ws2ident.html

New, unique identifiers are not necessarily well known, but this should not pose a problem. Applications that need to be protocol-independent are encouraged to select a protocol on the basis of its suitability rather than the values assigned to their socket_type or protocol fields. Protocol suitability is indicated by the communications attributes, such as message versus byte stream, and reliable versus unreliable, that are contained in the protocol WSAPROTOCOL_INFO structure. Selecting protocols on the basis of suitability as opposed to well-known protocol names and socket types lets protocol-independent applications take advantage of new transport protocols and their associated media types, as they become available.

The server half of a client/server application benefits by establishing listening sockets on all suitable transport protocols. Then, the client can establish its connection using any suitable protocol. For example, this would let a client application be unmodified whether it was running on a desktop system connected through LAN or on a laptop using a wireless network.


Multiple Provider Restrictions on select

The select function is used to determine the status of one or more sockets in a set. For each socket, the caller can request information on read, write, or error status. A set of sockets is indicated by an FD_SET structure.

Windows Sockets 2 allows an application to use more than one service provider, but the select function is limited to a set of sockets associated with a single service provider. This does not in any way restrict an application from having multiple sockets open through multiple providers.

There are two ways to determine the status of set of sockets that span more than one service provider: 1) using the WSAWaitForMultipleEvents or WSAEventSelect functions when blocking semantics are employed, and 2) using the WSAAsyncSelect function when nonblocking operations are employed.

When an application needs to use blocking semantics on a set of sockets that spans multiple providers, WSAWaitForMultipleEvents is recommended. The application can also use the WSAEventSelect function, which allows the FD_XXX network events (see WSAEventSelect) to associate with an event object and be handled from within the event object paradigm (described in Overlapped I/O and Event Objects).

The WSAAsyncSelect function is recommended when nonblocking operations are preferred. This function is not restricted to a single provider because it takes a socket descriptor as an input parameter.


Function Extension Mechanism

The Windows Sockets DLL, WS2_32.DLL, is no longer supplied by each individual stack vendor. As a result, it is no longer possible for a stack vendor to offer extended functionality by just adding entry points to the WS2_32.DLL. To overcome this limitation, Windows Sockets 2 takes advantage of the new WSAIoctl function to accommodate service providers who want to offer provider-specific functionality extensions. This mechanism assumes, of course, that an application is aware of a particular extension and understands both the semantics and syntax involved. Such information would typically be supplied by the service provider vendor.

In order to invoke an extension function, the application must first ask for a pointer to the desired function. This is done through the WSAIoctl function using the SIO_GET_EXTENSION_FUNCTION_POINTER command code. The input buffer to the WSAIoctl function contains an identifier for the desired extension function while the output buffer contains the function pointer itself. The application can then invoke the extension function directly without passing through the WS2_32.DLL.

The identifiers assigned to extension functions are globally unique identifiers (GUIDs) that are allocated by service provider vendors. Vendors who create extension functions are urged to publish full details about the function including the syntax of the function prototype. This makes it possible for common and popular extension functions to be offered by more than one service provider vendor. An application can obtain the function pointer and use the function without needing to know anything about the particular service provider that implements the function.


Debug and Trace Facilities

Windows Sockets 2 application developers need to isolate bugs in 1) the application, 2) the WS2_32.DLL or one of the compatibility "shim" DLLs, or 3) the service provider. Windows Sockets 2 addresses this need through a specially devised version of the WS2_32.DLL and a separate debug/trace DLL. This combination allows all procedure calls across the Windows Sockets 2 API or SPI to be monitored and, to some extent, be controlled.

Developers can use this mechanism to trace procedure calls, procedure returns, parameter values, and return values. Parameter values and return values can be altered on procedure call or procedure return. If desired, a procedure call can be prevented or redirected. With access to this level of information and control, a developer can isolate any problem in the application, WS2_32.DLL, or service provider.

The Windows Sockets 2 SDK includes the debug WS2_32.DLL, a sample debug/trace DLL, and a document containing a detailed description of the components. The sample debug/trace DLL is provided in both source and object form. Developers are free to use the source to develop versions of the debug/trace DLL that meet their specific needs.


Name Resolution

Windows Sockets 2 includes provisions for standardizing the way applications access and use the various network name resolution services. Windows Sockets 2 applications do not need to be aware of the widely differing interfaces associated with name services such as DNS, NIS, X.500, SAP, and others. An introduction to this topic and the details of the functions are currently located in Protocol-Independent Name Resolution.


Overlapped I/O and Event Objects

Windows Sockets 2 introduces overlapped I/O and requires that all transport providers support this capability. Overlapped I/O follows the model established in Win32 and can be performed only on sockets created through the WSASocket function with the WSA_FLAG_OVERLAPPED flag set or sockets created through the socket function.

Note Creating a socket with the overlapped attribute has no impact on whether a socket is currently in the blocking or nonblocking mode. Sockets created with the overlapped attribute can be used to perform overlapped I/O—doing so does not change the blocking mode of a socket. Since overlapped I/O operations do not block, the blocking mode of a socket is irrelevant for these operations.

For receiving, applications use the WSARecv or WSARecvFrom functions to supply buffers into which data is to be received. If one or more buffers are posted prior to the time when data has been received by the network, that data could be placed in the user's buffers immediately as it arrives. Thus, it can avoid the copy operation that would otherwise occur at the time the recv or recvfrom function is invoked. If data is already present when receive buffers are posted, it is copied immediately into the user's buffers.

If data arrives when no receive buffers have been posted by the application, the network resorts to the familiar synchronous style of operation. That is, the incoming data is buffered internally until the application issues a receive call and thereby supplies a buffer into which the data can be copied. An exception to this is when the appliation uses setsockopt to set the size of the receive buffer to zero. In this instance, reliable protocols would only allow data to be received when application buffers had been posted and data on unreliable protocols would be lost.

On the sending side, applications use WSASend or WSASendTo to supply pointers to filled buffers and then agree to not disturb the buffers in any way until the network has consumed the buffer's contents.

Overlapped send and receive calls return immediately. A return value of zero indicates that the I/O operation was completed immediately and that the corresponding completion indication already occurred. That is, the associated event object has been signaled, or a completion routine has been queued and will be executed when the calling thread gets into the alertable wait state.

A return value of SOCKET_ERROR coupled with an error code of WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that a subsequent indication will be provided when send buffers have been consumed or when a receive operation has been completed. However, for sockets that are byte-stream style, the completion indication occurs whenever the incoming data is exhausted, regardless of whether the buffers are full. Any other error code indicates that the overlapped operation was not successfully initiated and that no completion indication will be forthcoming.

Both send and receive operations can be overlapped. The receive functions can be invoked several times to post receive buffers in preparation for incoming data, and the send functions can be invoked several times to queue multiple buffers to send. While the application can rely upon a series of overlapped send buffers being sent in the order supplied, the corresponding completion indications might occur in a different order. Likewise, on the receiving side, buffers will be filled in the order they are supplied, but the completion indications might occur in a different order.

Canceling individual overlapped operations pending on a given socket is impossible. However, the closesocket function can be called to close the socket and eventually discontinue all pending operations.

The deferred completion feature of overlapped I/O is also available for WSAIoctl, which is an enhanced version of ioctlsocket.


Event Objects

Introducing overlapped I/O requires a mechanism for applications to unambiguously associate send and receive requests with their subsequent completion indications. In Windows Sockets 2, this is accomplished with event objects that are modeled after Win32 events. Windows Sockets event objects are fairly simple constructs that can be created and closed, set and cleared, and waited upon and polled. Their prime utility is the ability of an application to block and wait until one or more event objects become set.

Applications use WSACreateEvent to obtain an event object handle that can then be supplied as a required parameter to the overlapped versions of send and receive calls (WSASend, WSASendTo, WSARecv, WSARecvFrom). The event object, which is cleared when first created, is set by the transport providers when the associated overlapped I/O operation has completed (either successfully or with errors). Each event object created by WSACreateEvent should have a matching WSACloseEvent to destroy it.

Event objects are also used in WSAEventSelect to associate one or more FD_XXX network events with an event object. This is described in Asynchronous Notification Using Event Objects.

In 32-bit environments, event object – related functions, including WSACreateEvent, WSACloseEvent, WSASetEvent, WSAResetEvent, and WSAWaitForMultipleEvents are directly mapped to the corresponding native Win32 functions, using the same function name, but without the WSA prefix.


Receiving Completion Indications

Several options are available for receiving completion indications, thus providing applications with appropriate levels of flexibility. These include: waiting (or blocking) on event objects, polling event objects, and socket I/O completion routines.

Blocking and Waiting for Completion Indication

Applications can block while waiting for one or more event objects to become set using the WSAWaitForMultipleEvents function. In Win32 implementations, the process or thread will truly block. Since Windows Sockets 2 event objects are implemented as Win32 events, the native Win32 function, WaitForMultipleObjects can also be used for this purpose. This is especially useful if the thread needs to wait on both socket and nonsocket events.

Polling for Completion Indication

Applications that prefer not to block can use the WSAGetOverlappedResult function to poll for the completion status associated with any particular event object. This function indicates whether or not the overlapped operation has completed, and if completed, arranges for the WSAGetLastError function to retrieve the error status of the overlapped operation.

Using socket I/O completion routines

The functions used to initiate overlapped I/O (WSASend, WSASendTo, WSARecv, WSARecvFrom) all take lpCompletionRoutine as an optional input parameter. This is a pointer to an application-specific function that will be called after a successfully initiated overlapped I/O operation was completed (successfully or otherwise). The completion routine follows the same rules as stipulated for Win32 file I/O completion routines. That is, the completion routine will not be invoked until the thread is in an alertable wait state, such as when the function WSAWaitForMultipleEvents is invoked with the fAlertable flag set. An application that uses the completion routine option for a particular overlapped I/O request may not use the "wait" option of WSAGetOverlappedResult for that same overlapped I/O request.

The transports allow an application to invoke send and receive operations from within the context of the socket I/O completion routine and guarantee that, for a given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

Summary of overlapped completion indication mechanisms

The particular overlapped I/O completion indication to be used for a given overlapped operation is determined by whether the application supplies a pointer to a completion function, whether a WSAOVERLAPPED structure is referenced, and by the value of the hEvent member within the WSAOVERLAPPED structure (if supplied). The following table summarizes the completion semantics for an overlapped socket and shows the various combinations of lpOverlapped, hEvent, and lpCompletionRoutine:

lpOverlapped | hEvent | lpCompletionRoutine | Completion Indication
NULL | not applicable | ignored | Operation completes synchronously. It behaves as if it were a nonoverlapped socket.
!NULL | NULL | NULL | Operation completes overlapped, but there is no Windows Sockets 2-supported completion mechanism. The completion port mechanism (if supported) can be used in this case. Otherwise, there will be no completion notification.
!NULL | !NULL | NULL | Operation completes overlapped, notification by signaling event object.
!NULL | ignored | !NULL | Operation completes overlapped, notification by scheduling completion routine.


Asynchronous Notification Using Event Objects

The WSAEventSelect and WSAEnumNetworkEvents functions are provided to accommodate applications such as daemons and services that have no user interface (and hence do not use Windows handles). The WSAEventSelect function behaves exactly like the WSAAsyncSelect function. However, instead of causing a Windows message to be sent on the occurrence of an FD_XXX network event (for example, FD_READ and FD_WRITE), an application-designated event object is set.

Also, the fact that a particular FD_XXX network event has occurred is "remembered" by the service provider. The application can call WSAEnumNetworkEvents to have the current contents of the network event memory copied to an application-supplied buffer and to have the network event memory automatically cleared. If needed, the application can also designate a particular event object that is cleared along with the network event memory.


Flow Specification Quality of Service

The basic Quality of Service (QOS) mechanism in Windows Sockets 2 descends from the flow specification as described in RFC 1363, dated September 1992. Following is a brief overview of this concept:

Flow specifications describe a set of characteristics about a proposed, unidirectional flow through the network. An application can associate a pair of flow specifications with a socket (one for each direction) at the time a connection request is made using WSAConnect, or at other times using WSAIoctl with the SIO_SET_QOS/SIO_SET_GROUP_QOS command. Flow specifications indicate parametrically what level of service is required and provide a feedback mechanism for applications to use in adapting to network conditions.

This is the usage model for QOS in Windows Sockets 2: An application can establish its QOS requirements at any time with WSAIoctl or coincident with the connect operation with WSAConnect. For connection-oriented transports, it is often most convenient for an application to use the WSAConnect function because any QOS values supplied at connect time supersede those supplied earlier with the WSAIoctl function. If the WSAConnect function completes successfully, the application knows that its QOS request has been honored by the network. The application is then free to use the socket for data exchange. If the connect operation fails because of limited resources, an appropriate error indication is given. At this point, the application can scale down its service request and try again, or it can give up.

Transport providers update the associated flowspec structures after every connection attempt (successful or otherwise) in order to indicate, as well as possible, the existing network conditions. (Updating with the Default Values will indicate that information about the current network conditions is not available.) This update from the service provider about current network conditions is especially useful when the application's QOS request consists entirely of the default (unspecified) values, which any service provider should be able to meet.

Applications expect to use this information about current network conditions to guide their use of the network, including any subsequent QOS requests. However, the information provided by the transport in the updated flowspec structure is only an indication. It might be little more than a rough estimate that only applies to the first hop and not to the complete, end-to-end connection. The application must take appropriate precautions in interpreting this information.

Connectionless sockets can also use the WSAConnect function to establish a specified QOS level to a single designated peer. Otherwise, connectionless sockets use the WSAIoctl function to stipulate the initial QOS request, and any subsequent QOS renegotiations.

Even after a flow is established, conditions in the network can change or one of the communicating parties might invoke a QOS renegotiation that results in a reduction (or increase) in the available service level. A notification mechanism is included that utilizes the usual Windows Sockets notification techniques (FD_QOS and FD_GROUP_QOS events) to indicate to the application that QOS levels have changed.

A service provider generates FD_QOS/FD_GROUP_QOS notifications when the current level of service supported is significantly different (especially in the negative direction) from what was last reported as a basic guideline. The application should use the WSAIoctl function with SIO_GET_QOS and/or SIO_GET_GROUP_QOS to retrieve the corresponding flowspec structure and examine them in order to discover what aspect of the service level has changed. The QOS structures will be updated where appropriate. regardless of whether FD_QOS/FD_GROUP_QOS is registered and generated.

If the updated level of service is not acceptable, the application can adjust itself to accommodate it, attempt to renegotiate QOS, or close the socket. If a renegotiation is attempted, a successful return from the WSAIoctl function indicates that the revised QOS request was accepted., Otherwise, an appropriate error will be indicated.

The flow specifications proposed for Windows Sockets 2 divide QOS characteristics into the following general areas:

Source Traffic Description
The manner in which the application's traffic will be injected into the network. This includes specifications for the token rate, the token bucket size, and the peak bandwidth. Though the bandwidth requirement is expressed in terms of a token rate, a service provider need not implement token buckets. Any traffic management scheme that yields equivalent behavior is permitted.
Latency
Upper limits on the amount of delay and delay variation that are acceptable.
Level of service guarantee
Whether or not an absolute guarantee is required as opposed to best effort. Providers that have no feasible way to provide the level of service requested are expected to fail the connection attempt.
Provider-specific parameters
The flow specification itself can be extended in ways that are particular to specific providers.


QOS Templates

It is possible for QOS templates to be established for well-known media flows such as H.323, G.711, and others. The WSAGetQOSByName function can be used to obtain the appropriate QOS structure for named media streams. It is up to each service provider to determine the appropriate values for each element in the QOS structure, as well as any protocol or media-dependent QOS extensions. The documentation for the WSAGetQOSByName function will be periodically updated with a list of flow specifications and general descriptions as they become well-known. The WSAGetQOS ByName function can also be used to enumerate the set of known QOS template names.


Default Values

A default flowspec structure is associated with each eligible socket at the time it is created. The member values for the default flowspec structure, in all cases, indicate that no particular flow characteristics are being requested from the network. Applications only need to modify values important to that application, but must be aware that there is some coupling between fields such as TokenRate and TokenBucketSize. These are the values for the default flow spec:

TokenRate =           0XFFFFFF(not specified)
TokenBucketSize =     0XFFFFFF(not specified)
PeakBandwidth =       0XFFFFFF(not specified)
Latency =             0XFFFFFF(not specified)
DelayVariation =      0XFFFFFF(not specified)
ServiceType =         SERVICETYPE
MaxSduSize =…         0XFFFFFF
MinimumPolicedSize =  0XFFFFFF


Socket Groups

Important Reserved for future use with socket groups:

Windows Sockets 2 introduces a number of function parameters, data types, structure members, and manifest constant values that are reserved for future use in grouping sockets together. As of the version 2.2.1 of the specification, the intended future use of these items is fully described, however, none of the group-related parameters is interpreted in software releases corresponding to the version 2.2.1 specification. Since a client always has the option to elect not to use socket groups, there are always default values and behaviors defined for group-related definitions. It is simple for an application not employing socket groups to use default values in such a fashion that the application will not be harmed if and when socket groups are "turned on" in the future. Definitions related to socket groups are marked in version 2.2.1 specification with the phrase: "Reserved for future use with socket groups" preceding the description of the intended future use.

Windows Sockets 2 introduces the concept of a socket group as a means for an application (or cooperating set of applications) to indicate to an underlying service provider that a particular set of sockets are related, and that the group thus formed has certain attributes. Group attributes include relative priorities of the individual sockets within the group and a group's quality of service specification.

Applications needing to exchange multimedia streams over the network benefit by establishing a specific relationship among the set of sockets being utilized. This can include, as a minimum, an indication to the service provider about the relative priorities of the media streams being carried. For example, a conferencing application would likely give the socket used for carrying the audio stream a higher priority than the socket used for the video stream. Furthermore, there are transport providers (for example, digital telephony and ATM) that can utilize a group, quality-of-service specification to determine the appropriate characteristics for the underlying call or circuit connection. The sockets within a group are then multiplexed in the usual manner over this call. By allowing the application to identify the sockets that make up a group and to specify the required group attributes, service providers can operate with maximum effectiveness.

The WSASocket and WSAAccept functions are two new functions used to specifically create and join a socket group coincident with creating a new socket. Socket group identifiers can be retrieved by using getsockopt with option SO_GROUP_ID. Relative priority can be accessed by using get/setsockopt with option SO_GROUP_PRIORITY.


Shared Sockets

The WSADuplicateSocket function is introduced to enable socket sharing across processes. A source process calls WSADuplicateSocket to obtain a special WSAPROTOCOL_INFO structure for a target process ID. It uses some interprocess communications (IPC) mechanism to pass the contents of this structure to a target process. The target process then uses the WSAPROTOCOL_INFO structure in a call to WSPSocket. The socket descriptor returned by this function will be an additional socket descriptor to an underlying socket which thus becomes shared. Sockets can be shared among threads in a given process without using the WSADuplicateSocket function because a socket descriptor is valid in all threads of a process.

The two (or more) descriptors that reference a shared socket can be used independently as far as I/O is concerned. However, the Windows Sockets interface does not implement any type of access control, so the processes must coordinate any operations on a shared socket. A typical example of sharing sockets is to use one process for creating sockets and establishing connections. This process then hands off sockets to other processes that are responsible for information exchange.

The WSADuplicateSocket function creates socket descriptors and not the underlying socket. As a result, all the states associated with a socket are held in common across all the descriptors. For example, a setsockopt operation performed using one descriptor is subsequently visible using a getsockopt from any or all descriptors. A process can call closesocket on a duplicated socket and the descriptor will become deallocated. The underlying socket, however, will remain open until closesocket is called with the last remaining descriptor.

Notification on shared sockets is subject to the usual constraints of the WSAAsyncSelect and WSAEventSelect functions. Issuing either of these calls using any of the shared descriptors cancels any previous event registration for the socket, regardless of which descriptor was used to make that registration. Thus, for example, it would not be possible to have process A receive FD_READ events and process B receive FD_WRITE events. For situations when such tight coordination is required, it is suggested that developers use threads instead of separate processes.


Enhanced Functionality During Connection Setup and Teardown

The WSAAccept function lets an application obtain caller information such as caller ID and QOS before deciding whether to accept an incoming connection request. This is done with a callback to an application-supplied condition function.

User-to-user data specified by parameters in the WSAConnect function and the condition function of WSAAccept can be transferred to the peer during connection establishment, provided this feature is supported by the service provider.

It is also possible (for protocols that support this) to exchange user data between the endpoints at connection teardown time. The end that initiates the teardown can call the WSASendDisconnect function to indicate that no more data be sent and to initiate the connection teardown sequence. For certain protocols, part of this teardown sequence is the delivery of disconnect data from the teardown initiator. After receiving notice that the remote end has initiated the teardown sequence (typically by the FD_CLOSE indication), the WSARecvDisconnect function can be called to receive the disconnect data, if any.

To illustrate how disconnect data can be used, consider the following scenario. The client half of a client/server application is responsible for terminating a socket connection. Coincident with the termination, it provides (using disconnect data) the total number of transactions it processed with the server. The server in turn responds with the cumulative total of transactions that it has processed with all clients. The sequence of calls and indications might occur as follows:

Client Side | Server Side
(1) Invoke WSASendDisconnect to conclude session and supply transaction total |
 | (2) Get FD_CLOSE, recv with a return value of zero, or WSAEDISCON error return from WSARecv indicating graceful shutdown in progress
 | (3) Invoke WSARecvDisconnect to get client's transaction total
 | (4) Compute cumulative grand total of all transactions
 | (5) Invoke WSASendDisconnect to transmit grand total
(6) Receive FD_CLOSE indication | (5a) Invoke closesocket
(7) Invoke WSARecvDisconnect to receive and store cumulative grand total of transactions |
(8) Invoke closesocket |

Note that step (5a) must follow step (5), but has no timing relationship with step (6), (7), or (8).


Extended Byte Order Conversion Routines

Windows Sockets 2 does not assume that the network byte order for all protocols is the same. A set of conversion routines is supplied for converting 16-bit and 32-bit quantities to and from network byte order. These routines take as an input parameter parameter the socket handle that has a WSAPROTOCOL_INFO structure associated with it. The NetworkByteOrder member of the WSAPROTOCOL_INFO structure specifies the desired network byte order (currently either "big-endian" or "little-endian").


Support for Scatter/Gather I/O

The WSASend, WSASendTo, WSARecv, and WSARecvFrom functions all take an array of application buffers as input parameters and can be used for scatter/gather (or vectored) I/O. This can be very useful in instances where portions of each message being transmitted consist of one or more fixed-length "header" components in addition to message body. Such header components need not be concatenated by the application into a single contiguous buffer prior to sending. Likewise on receiving, the header components can be automatically split off into separate buffers, leaving the message body "pure."

When receiving into multiple buffers, completion occurs as data arrives from the network, regardless of whether all the supplied buffers are utilized.


Protocol-Independent Multicast and Multipoint

Windows Sockets 2 provides a generic method for utilizing the multipoint and multicast capabilities of transports. This generic method implements these features just as it allows the basic data transport capabilities of numerous transport protocols to be accessed. The term multipoint is used hereafter to refer to both multicast and multipoint communications.

Current multipoint implementations (for example, IP multicast, ST-II, T.120, and ATM UNI) vary widely. How nodes join a multipoint session, whether a particular node is designated as a central or root node, and whether data is exchanged between all nodes or only between a root node and the various leaf nodes differ among implementations. The WSAPROTOCOL_INFO structure for Windows Sockets 2 is used to declare the various multipoint attributes of a protocol. By examining these attributes, the programmer knows what conventions to follow with the applicable Windows Sockets 2 functions to setup, utilize and teardown multipoint sessions.

Following is a summary of the features of Windows Sockets 2 that support multipoint:

  • Two attribute bits in the WSAPROTOCOL_INFO structure.
  • Four flags defined for the dwFlags parameter of the WSASocket function.
  • One function, WSAJoinLeaf, for adding leaf nodes into a multipoint session
  • Two WSAIoctl command codes for controlling multipoint loopback and establishing the scope for multicast transmissions. (The latter corresponds to the IP multicast time-to-live or TTL parameter.)

Note The inclusion of these multipoint features in Windows Sockets 2 does not preclude an application from using an existing protocol-dependent interface, such as the Deering socket options for IP multicast.

See Multipoint and Multicast Semantics for detailed information on how the various multipoint schemes are characterized and how the applicable features of Windows Sockets 2 are utilized.


Summary of New Socket Options

The new socket options for Windows Sockets 2 are summarized in the following table. See getsockopt and setsockopt for detailed information on these options. The other new protocol-specific socket options can be found in the Protocol-specific Annex (a separate document included with the Platform SDK).

Value | Type | Meaning | Default | Note
SO_GROUP_ID | GROUP | Reserved for future use with socket groups: The identifier of the group to which this socket belongs. | NULL | get only
SO_GROUP _PRIORITY | int | Reserved for future use with socket groups: The relative priority for sockets that are part of a socket group. | 0 |
SO_MAX_MSG _SIZE | int | Maximum outbound (send) size of a message for message-oriented socket types. There is no provision for finding out the maximum inbound message size. Has no meaning for stream-oriented sockets. | Implementation dependent | get only
SO_PROTOCOL _INFO | struct WSAPROTOCOL_INFO | Description of protocol info for protocol that is bound to this socket. | protocol dependent | get only
PVD_CONFIG | char FAR * | An opaque data structure object containing configuration information of the service provider. | Implementation dependent |


Summary of New Socket Ioctl Opcodes

The new socket ioctl opcodes for Windows Sockets 2 are summarized in the following table. See WSAIoctl for detailed information on these opcodes. The WSAIoctl function also supports all the ioctl opcodes specified in ioctlsocket. Theother new protocol-specific ioctl opcodes can be found in the Protocol-specific Annex (a separate document included with the Platform SDK).

Opcode | Input Type | Output Type | Meaning
SIO_ASSOCIATE _HANDLE | companion API dependent | <not used> | Associate the socket with the specified handle of a companion interface.
SIO_ENABLE _CIRCULAR_QUEUEING | <not used> | <not used> | Circular queuing is enabled.
SIO_FIND_ROUTE | struct sockaddr | <not used> | Request the route to the specified address to be discovered.
SIO_FLUSH | <not used> | <not used> | Discard current contents of the sending queue.
SIO_GET_BROADCAST _ADDRESS | <not used> | struct sockaddr | Retrieve the protocol-specific broadcast address to be used in sendto/WSASendTo.
SIO_GET_QOS | <not used> | QOS | Retrieve current flow specification(s) for the socket.
SIO_GET_GROUP_QOS | <not used> | QOS | Reserved for future use with socket groups: Retrieve current group flow specification(s) for the group this socket belongs to.
SIO_MULTIPOINT _LOOPBACK | BOOL | <not used> | Control whether data sent in a multipoint session will also be received by the same socket on the local host.
SIO_MULTICAST _SCOPE | int | <not used> | Specify the scope over which multicast transmissions will occur.
SIO_SET_QOS | QOS | <not used> | Establish new flow specification(s) for the socket.
SIO_SET_GROUP_QOS | QOS | <not used> | Reserved for future use with socket groups: Establish new group flow specification(s) for the group this socket belongs to.
SIO_TRANSLATE _HANDLE | int | companion API dependent | Obtain a corresponding handle for socket s that is valid in the context of a companion interface.
SIO_ROUTING _INTERFACE_QUERY | SOCKADDR | SOCKADDR | Obtain the address of local interface which should be used to send to the specified address
SIO_ROUTING _INTERFACE_CHANGE | SOCKADDR | <not used> | Request notification of changes in information reported via SIO_ROUTING_INTERFACE_QUERY for the specified address
SIO_ADDRESS _LIST_QUERY | <not used> | SOCKET _ADDRESS _LIST | Obtain the list of addresses to which application can bind.
SIO_ADDRESS _LIST_CHANGE | <not used> | <not used> | Request notification of changes in information reported via SIO_ADDRESS_LIST_QUERY


Summary of New Functions

The new API functions for Windows Sockets 2 are summarized in the following table.

Data Transport Functions

Function | Description
WSAAccept1 | An extended version of accept which allows for conditional acceptance and socket grouping.
WSACloseEvent | Destroys an event object.
WSAConnect1 | An extended version of connect which allows for exchange of connect data and QOS specification.
WSACreateEvent | Creates an event object.
WSADuplicateSocket | Creates a new socket descriptor for a shared socket.
WSAEnumNetworkEvents | Discovers occurrences of network events.
WSAEnumProtocols | Retrieves information about each available protocol.
WSAEventSelect | Associates network events with an event object.
WSAGetOverlappedResult | Gets completion status of overlapped operation.
WSAGetQOSByName | Supplies QOS parameters based on a well-known service name.
WSAHtonl | Extended version of htonl.
WSAHtons | Extended version of htons.
WSAIoctl1 | Overlapped-capable version of ioctlsocket.
WSAJoinLeaf1 | Joins a leaf node into a multipoint session.
WSANtohl | Extended version of ntohl.
WSANtohs | Extended version of ntohs.
WSAProviderConfigChange | Receive notifications of service providers being installed/removed.
WSARecv1 | An extended version of recv which accommodates scatter/gather I/O, overlapped sockets, and provides the flags parameter as IN OUT.
WSARecvDisconnect | Terminates reception on a socket and retrieves the disconnect data, if the socket is connection-oriented.
WSARecvFrom1 | An extended version of recvfrom which accommodates scatter/gather I/O, overlapped sockets, and provides the flags parameter as IN OUT.
WSAResetEvent | Resets an event object.
WSASend1 | An extended version of send which accommodates scatter/gather I/O and overlapped sockets.
WSASendDisconnect | Initiates termination of a socket connection and optionally sends disconnect data.
WSASendTo1 | An extended version of sendto which accommodates scatter/gather I/O and overlapped sockets.
WSASetEvent | Sets an event object.
WSASocket | An extended version of socket which takes a WSAPROTOCOL_INFO structure as input and allows overlapped sockets to be created. Also allows socket groups to be formed.
WSAWaitForMultipleEvents1 | Blocks on multiple event objects.
1 The routine can block if acting on a blocking socket.

Name Registration and Resolution Functions

Function | Description
WSAAddressToString | Convert an address structure into a human-readable numeric string
WSAEnumNameSpaceProviders | Retrieve the list of available Name Registration and Resolution service providers
WSAGetServiceClassInfo | Retrieves all of the class-specific information pertaining to a service class
WSAGetServiceClassNameByClassId | Returns the name of the service associated with the given type
WSAInstallServiceClass | Create a new new service class type and store its class-specific information
WSALookupServiceBegin | Initiate a client query to retrieve name information as constrained by a WSAQUERYSET data structure
WSALookupServiceEnd | Finish a client query started by WSALookupServiceBegin and free resources associated with the query
WSALookupServiceNext | Retrieve the next unit of name information from a client query initiated by WSALookupServiceBegin
WSARemoveServiceClass | Permanently removes a service class type
WSASetService | Register or deregister a service instance within one or more name spaces
WSAStringToAddress | Convert a human-readable numeric string to a socket address structure suitable for passing to Windows Sockets routines.


Windows Sockets Programming Considerations

This section provides programmers with important information on a number of topics. It is especially pertinent to those who are porting socket applications from UNIX-based environments or who are upgrading their Windows Sockets 1.1 applications to Windows Sockets 2.


Deviation from Berkeley Sockets

There are a few limited instances where Windows Sockets has had to divert from strict adherence to the Berkeley conventions, usually because of difficulties of implementation in a Windows environment.


Socket Data Type

A new data type, SOCKET, has been defined. This is needed because a Windows Sockets application cannot assume that socket descriptors are equivalent to file descriptors as they are in UNIX. Furthermore, in UNIX, all handles, including socket handles, are small, non-negative integers, and some applications make assumptions that this will be true. Windows Sockets handles have no restrictions, other than that the value INVALID_SOCKET is not a valid socket. Socket handles may take any value in the range 0 to INVALID_SOCKET-1.

Because the SOCKET type is unsigned, compiling existing source code from, for example, a UNIX environment may lead to compiler warnings about signed/unsigned data type mismatches.

This means, for example, that checking for errors when the socket and accept routines return should not be done by comparing the return value with -1, or seeing if the value is negative (both common, and legal, approaches in BSD). Instead, an application should use the manifest constant INVALID_SOCKET as defined in WINSOCK2.H. For example:

TYPICAL BSD STYLE:

s = socket(...);
if (s == -1)    /* or s < 0 */
    {...}

PREFERRED STYLE:

s = socket(...);
if (s == INVALID_SOCKET)
    {...}


select and FD_*

Because a SOCKET is no longer represented by the UNIX-style "small non-negative integer", the implementation of the select function was changed in Windows Sockets. Each set of sockets is still represented by the fd_set type, but instead of being stored as a bitmask the set is implemented as an array of SOCKETs. To avoid potential problems, applications must adhere to the use of the FD_XXX macros to set, initialize, clear, and check the fd_set structures.


Error codes - errno, h_errno & WSAGetLastError

Error codes set by Windows Sockets are NOT made available via the errno variable. Additionally, for the getXbyY class of functions, error codes are NOT made available via the h_errno variable. Instead, error codes are accessed by using the WSAGetLastError function. This function is provided in Windows Sockets as a precursor (and eventually an alias) for the Win32 function GetLastError. This is intended to provide a reliable way for a thread in a multi-threaded process to obtain per-thread error information.

For compatibility with BSD, an application may choose to include a line of the form:

#define errno WSAGetLastError

This will allow networking code which was written to use the global errno to work correctly in a single-threaded environment. There are, obviously, some drawbacks. If a source file includes code which inspects errno for both socket and non-socket functions, this mechanism cannot be used. Furthermore, it is not possible for an application to assign a new value to errno. (In Windows Sockets the function WSASetLastError may be used for this purpose.)

TYPICAL BSD STYLE:

r = recv(...);
if (r == -1
    && errno == EWOULDBLOCK)
    {...}

PREFERRED STYLE:

r = recv(...);
if (r == -1       /* (but see below) */
    && WSAGetLastError == EWOULDBLOCK)
    {...}

Although error constants consistent with 4.3 Berkeley Sockets are provided for compatibility purposes, applications should, where possible, use the "WSA" error code definitions. This is because error codes returned by certain WinSock routines fall into the standard range of error codes as defined by Microsoft C. Thus, a better version of the above source code fragment is:

r = recv(...);
if (r == -1       /* (but see below) */
    && WSAGetLastError == WSAEWOULDBLOCK)
    {...}

This specification defines a recommended set of error codes, and lists the possible errors that can be returned as a result of each function. It may be the case in some implementations that other Windows Sockets error codes will be returned in addition to those listed, and applications should be prepared to handle errors other than those enumerated under each function description. However Windows Sockets will not return any value that is not enumerated in the table of legal Windows Sockets errors given in the section Error Codes.


Pointers

All pointers used by applications with Windows Sockets should be FAR although this is only relevant to 16-bit applications and meaningless in a 32-bit. To facilitate this, data type definitions such as LPHOSTENT are provided.


Renamed functions

In two cases it was necessary to rename functions which are used in Berkeley Sockets in order to avoid clashes with other Win32 API functions.

close & closesocket

Sockets are represented by standard file descriptors in Berkeley Sockets, so the close function can be used to close sockets as well as regular files. While nothing in the Windows Sockets prevents an implementation from using regular file handles to identify sockets, nothing requires it either. Sockets must be closed by using the closesocket routine. Using the close routine to close a socket is incorrect and the effects of doing so are undefined by this specification.

ioctl & ioctlsocket/WSAIoctl

Various C language run-time systems use the ioctl routine for purposes unrelated to Windows Sockets. As a consequence, the ioctlsocket function and the WSAIoctl function were defined to handle socket functions that were performed by ioctl and fcntl in the Berkeley Software Distribution.


Maximum number of sockets supported

The maximum number of sockets supported by a particular Windows Sockets service provider is implementation specific. An application should make no assumptions about the availability of a certain number of sockets. For more information on this topic see WSAStartup.

The maximum number of sockets that an application can actually use is independent of the number of sockets supported by a particular implementation. The maximum number of sockets that a Windows Sockets application can use is determined at compile time by the manifest constant FD_SETSIZE. This value is used in constructing the fd_set structures used in select. The default value in WINSOCK2.H is 64. If an application is designed to be capable of working with more than 64 sockets, the implementor should define the manifest FD_SETSIZE in every source file before including WINSOCK2.H. One way of doing this may be to include the definition within the compiler options in the makefile. For example, you could add "-DFD_SETSIZE=128" as an option to the compiler command line for Microsoft C. It must be emphasized that defining FD_SETSIZE as a particular value has no effect on the actual number of sockets provided by a Windows Sockets service provider.


Include files

A number of standard Berkeley include files are supported for ease of porting existing source code based on Berkeley sockets. However, these Berkeley header files merely include the WINSOCK2.H include file, and it is therefore sufficient (and recommended) that Windows Sockets application source files just include WINSOCK2.H.


Return values on function failure

The manifest constant SOCKET_ERROR is provided for checking function failure. Although use of this constant is not mandatory, it is recommended. The following example illustrates the use of the SOCKET_ERROR constant:

TYPICAL BSD STYLE:

r = recv(...);
if (r == -1     /* or r < 0 */
    && errno == EWOULDBLOCK)
    {...}

PREFERRED STYLE:

r = recv(...);
if (r == SOCKET_ERROR
    && WSAGetLastError == WSAEWOULDBLOCK)
    {...}


Service Provided Raw Sockets

The Windows Sockets specification does not mandate that a Windows Sockets service provider support raw sockets, that is, sockets of type SOCK_RAW. However, service providers are encouraged to supply raw socket support. A Windows Sockets-compliant application that wishes to use raw sockets should attempt to open the socket with the socket call, and if it fails either attempt to use another socket type or indicate the failure to the user.


Byte Ordering

Care must always be taken to account for any differences between the byte ordering used by Intel Architecture and the byte ordering used on the wire by individual transport protocols. Any reference to an address or port number passed to or from a Windows Sockets routine must be in the network order for the protocol being utilized. In the case of IP, this includes the IP address and port fields of a sockaddr_in structure (but not the sin_family field).

Consider an application that normally contacts a server on the TCP port corresponding to the "time" service, but provides a mechanism for the user to specify an alternative port. The port number returned by getservbyname is already in network order, which is the format required for constructing an address so no translation is required. However, if the user elects to use a different port, entered as an integer, the application must convert this from host to TCP/IP network order (using the WSAHtons function) before using it to construct an address. Conversely, if the application were to display the number of the port within an address (returned by getpeername for example), the port number must be converted from network to host order (using WSANtohs) before it can be displayed.

Since the Intel and Internet byte orders are different, the conversions described above are unavoidable. Application writers are cautioned that they should use the standard conversion functions provided as part of Windows Sockets rather than writing their own conversion code since future implementations of Windows Sockets are likely to run on systems for which the host order is identical to the network byte order. Only applications that use the standard conversion functions are likely to be portable.


Windows Sockets Compatibility Issues

Windows Sockets 2 continues to support all of the Windows Sockets 1.1 semantics and function calls except for those dealing with psuedo-blocking. Since Windows Sockets 2 runs only in 32-bit, pre-emptively scheduled environments such as Windows NT and Windows 95, there is no need to implement the psuedo-blocking found in Windows Sockets 1.1. This means that the WSAEINPROGRESS error code will never be indicated and that the following Windows Sockets 1.1 functions are not available to Windows Sockets 2 applications:

  • WSACancelBlockingCall
  • WSAIsBlocking
  • WSASetBlockingHook
  • WSAUnhookBlockingHook

Windows Sockets 1.1 programs that are written to utilize psuedo-blocking will continue to operate correctly since they link to either WINSOCK.DLL or WSOCK32.DLL. Both continue to support the complete set of Windows Sockets 1.1 functions. In order for programs to become Windows Sockets 2 applications, some amount of code modification must occur. In most cases, you will substitute the judicious use of threads to accommodate processing that was being accomplished with a blocking hook function.


Default state for a socket's overlapped attribute

The socket function created sockets with the overlapped attribute set by default in the first WSOCK32.DLL, the 32-bit version of Windows Sockets 1.1. In order to insure backward compatibility with currently deployed WSOCK32.DLL implementations, this will continue to be the case for WinSock 2 as well. That is, in WinSock 2, sockets created with the socket function will have the overlapped attribute. However, in order to be more compatible with the rest of the Win32 API, sockets created with WSASocket will, by default, NOT have the overlapped attribute. This attribute will only be applied if the WSA_FLAG_OVERLAPPED bit is set.


Windows Sockets 1.1 Blocking routines & EINPROGRESS

One major issue in porting applications from a Berkeley sockets environment to a Windows environment involves "blocking"; that is, invoking a function that does not return until the associated operation is completed. A problem arises when the operation takes an arbitrarily long time to complete: an example is a recv, which might block until data has been received from the peer system. The default behavior within the Berkeley sockets model is for a socket to operate in a blocking mode unless the programmer explicitly requests that operations be treated as nonblocking. Windows Sockets 1.1 environments could not assume pre-emptive scheduling. Therefore, it was strongly recommended that programmers use the nonblocking (asynchronous) operations if at all possible with Windows Sockets 1.1. Because this was not always possible, the psuedo-blocking facilities described below were provided.

Note Windows Sockets 2 only runs on pre-emptive 32-bit operating systems where deadlocks are not a problem. Programming practices for recommended for Windows Sockets 1.1 are not necessary in Windows Sockets 2.

Even on a blocking socket, some functions — bind, getsockopt, and getpeername for example — complete immediately. There is no difference between a blocking and a nonblocking operation for those functions. Other operations, such as recv, can complete immediately or could take an arbitrary time to complete, depending on various transport conditions. When applied to a blocking socket, these operations are referred to as blocking operations. All routines that can block are listed with an asterisk in the tables above and below.

With 16-bit Windows Sockets 1.1, a blocking operation that cannot complete immediately is handled by psuedo-blocking as follows. The service provider initiates the operation, then enters a loop in which it dispatches any Windows messages (yielding the processor to another thread if necessary), and then checks for the completion of the Windows Sockets function. If the function has completed, or if WSACancelBlockingCall has been invoked, the blocking function completes with an appropriate result.

A service provider must allow installation of a blocking hook function that does not process messages in order to avoid the possibility of re-entrant messages while a blocking operation is outstanding. The simplest such blocking hook function would return FALSE. If a Windows Sockets DLL depends on messages for internal operation, it can execute PeekMessage(hMyWnd...) before executing the application blocking hook so that it can get its messages without affecting the rest of the system.

In a 16-bit Windows Sockets 1.1 environment, if a Windows message is received for a process for which a blocking operation is in progress, there is a risk that the application will attempt to issue another Windows Sockets call. Because of the difficulty in managing this condition safely, Windows Sockets 1.1 does not support such application behavior. An application it not permitted to make more than one nested Windows Sockets function calls. Only one outstanding function call will be allowed for a particular task. The only exceptions are two functions that are provided to assist the programmer in this situation: WSAIsBlocking and WSACancelBlockingCall.

The WSAIsBlocking function can be called at any time to determine whether or not a blocking Windows Sockets 1.1 call is in progress. Similarly, the WSACancelBlockingCall fucntion can be called at any time to cancel an in-progress blocking call. Any other nesting of Windows Sockets functions will fail with the error WSAEINPROGRESS.

It should be emphasized that this restriction applies to both blocking and non-blocking operations. For Windows Sockets 2 applications that negotiate version 2.0 or higher at the time of calling WSAStartup, no restriction on the nesting of operations exits. Operations can become nested under some rare circumstances such as during a WSAAccept conditional-acceptance callback, or if a service provider in turn invokes a Windows Sockets 2 function.

Although this mechanism is sufficient for simple applications, it cannot support the complex message-dispatching requirements of more advanced applications (for example, those using the MDI model). For such applications, the Windows Sockets API includes the function WSASetBlockingHook, which allows the application to specify a special routine which will be called instead of the default message dispatch routine described above.

The Windows Sockets provider calls the blocking hook only if all of the following are true: the routine is one that is defined as being able to block, the specified socket is a blocking socket, and the request cannot be completed immediately. (A socket is set to blocking by default, but the IOCTL FIONBIO or the WSAAsyncSelect function set a socket to nonblocking mode.)

The blocking hook will never be called and the application does not need to be concerned with the re-entrancy issues the blocking hook can introduce if an application follows these guideline:

  • It uses only nonblocking sockets, and;
  • It uses the WSAAsyncSelect and/or the WSAAsyncGetXByY routines instead of select and the getXbyY routines.

If a Windows Sockets 1.1 application invokes an asynchronous or nonblocking operation that takes a pointer to a memory object (a buffer, or a global variable for example) as an argument, it is the responsibility of the application to ensure that the object is available to Windows Sockets throughout the operation. The application must not invoke any Windows function that might affect the mapping or addressability of the memory involved.


Graceful shutdown, linger options and socket closure

The following material is provided as clarification for the subject of shutting down socket connections closing the sockets. It is important to distinguish the difference between shutting down a socket connection and closing a socket. Shutting down a socket connection involves an exchange of protocol messages between the two endpoints, hereafter referred to as a shutdown sequence. Two general classes of shutdown sequences are defined: graceful and abortive (also called "hard"). In a graceful shutdown sequence, any data that has been queued but not yet transmitted can be sent prior to the connection being closed. In an abortive shutdown, any unsent data is lost. The occurrence of a shutdown sequence (graceful or abortive) can also be used to provide an FD_CLOSE indication to the associated applications signifying that a shutdown is in progress.

Closing a socket, on the other hand, causes the socket handle to become deallocated so that the application can no longer reference or use the socket in any manner.

In Windows Sockets, both the shutdown function, and the WSASendDisconnect function can be used to initiate a shutdown sequence, while the closesocket function is used to deallocate socket handles and free up any associated resources. Some amount of confusion arises, however, from the fact that the closesocket function will implicitly cause a shutdown sequence to occur if it has not already happened. In fact, it has become a rather common programming practice to rely on this feature and use closesocket to both initiate the shutdown sequence and deallocate the socket handle.

To facilitate this usage, the sockets interface provides for controls by way of the socket option mechanism that allow the programmer to indicate whether the implicit shutdown sequence should be graceful or abortive, and also whether the closesocket function should linger (that is not complete immediately) to allow time for a graceful shutdown sequence to complete. These important distinctions and the ramifications of using closesocket in this manner have not been widely understood.

By establishing appropriate values for the socket options SO_LINGER and SO_DONTLINGER, the following types of behavior can be obtained with the closesocket function:

  • Abortive shutdown sequence, immediate return from closesocket.
  • Graceful shutdown, delaying return until either shutdown sequence completes or a specified time interval elapses. If the time interval expires before the graceful shutdown sequence completes, an abortive shutdown sequence occurs, and closesocket returns.
  • Graceful shutdown, immediate return — allowing the shutdown sequence to complete in the background. Although this is the default behavior, the application has no way of knowing when (or whether) the graceful shutdown sequence actually completes.

One technique that can be used to minimize the chance of problems occurring during connection teardown is to avoid relying on an implicit shutdown being initiated by closesocket. Instead, use one of the two explicit shutdown functions, shutdown or WSASendDisconnect. This in turn will cause an FD_CLOSE indication to be received by the peer application indicating that all pending data has been received. To illustrate this, the following table shows the functions that would be invoked by the client and server components of an application, where the client is responsible for initiating a graceful shutdown.

Client Side | Server Side
(1) Invoke shutdown(s, SD_SEND) to signal end of session and that client has no more data to send. |
 | (2) Receive FD_CLOSE, indicating graceful shutdown in progress and that all data has been received.
 | (3) Send any remaining response data.
(5') Get FD_READ and invoke recv to get any response data sent by server | (4) Invoke shutdown(s, SD_SEND) to indicate server has no more data to send.
(5) Receive FD_CLOSE indication | (4') Invoke closesocket
(6) Invoke closesocket |

Note The timing sequence is maintained from step (1) to step (6) between the client and the server, except for step (4') and (5') which only has local timing significance in the sense that step (5) follows step (5') on the client side while step (4') follows step (4) on the server side, with no timing relationship with the remote party.


Protocol-independent Out-Of-Band data

The stream socket abstraction includes the notion of "out of band'' (OOB) data. Many protocols allow portions of incoming data to be marked as special in some way, and these special data blocks can be delivered to the user out of the normal sequence. Examples include "expedited data" in X.25 and other OSI protocols, and "urgent data" in BSD Unix's use of TCP. The next section describes OOB data handling in a protocol-independent manner. A discussion of OOB data implemented using TCP "urgent data" follows it. In the each discussion, the use of recv also implies recvfrom, WSARecv, and WSARecvFrom, and references to WSAAsyncSelect also apply to WSAEventSelect.

Protocol Independent OOB data

OOB data is a logically independent transmission channel associated with each pair of connected stream sockets. OOB data may be delivered to the user independently of normal data. The abstraction defines that the OOB data facilities must support the reliable delivery of at least one OOB data block at a time. This data block can contain at least one byte of data, and at least one OOB data block can be pending delivery to the user at any one time. For communications protocols that support in-band signaling (such as TCP, where the "urgent data" is delivered in sequence with the normal data), the system normally extracts the OOB data from the normal data stream and stores it separately (leaving a gap in the "normal" data stream). This allows users to choose between receiving the OOB data in order and receiving it out of sequence without having to buffer all the intervening data. It is possible to "peek'' at out-of-band data.

A user can determine if there is any OOB data waiting to be read using the ioctlsocket(SIOCATMARK) function (q.v.). For protocols where the concept of the "position" of the OOB data block within the normal data stream is meaningful such as TCP, a Windows Sockets service provider will maintain a conceptual "marker" indicating the position of the last byte of OOB data within the normal data stream. This is not necessary for the implementation of the ioctlsocket(SIOCATMARK) functionality - the presence or absence of OOB data is all that is required.

For protocols where the concept of the "position" of the OOB data block within the normal data stream is meaningful, an application might process out-of-band data "in-line", as part of the normal data stream. This is achieved by setting the socket option SO_OOBINLINE with setsockopt. For other protocols where the OOB data blocks are truly independent of the normal data stream, attempting to set SO_OOBINLINE will result in an error. An application can use the SIOCATMARK ioctlsocket command to determine whether there is any unread OOB data preceding the mark. For example, it can use this to resynchronize with its peer by ensuring that all data up to the mark in the data stream is discarded when appropriate.

With SO_OOBINLINE disabled (the default setting):

  • Windows Sockets notifies an application of an FD_OOB event, if the application registered for notification with WSAAsyncSelect, in exactly the same way FD_READ is used to notify of the presence of normal data. That is, FD_OOB is posted when OOB data arrives with no OOB data previously queued. The FD_OOB is also posted when data is read using the MSG_OOB flag while some OOB data remains queued after the read operation has returned. FD_READ messages are not posted for OOB data.
  • Windows Sockets returns from select with the appropriate exceptfds socket set if OOB data is queued on the socket.
  • The application can call recv with MSG_OOB to read the urgent data block at any time. The block of OOB data "jumps the queue".
  • The application can call recv without MSG_OOB to read the normal data stream. The OOB data block will not appear in the data stream with "normal data." If OOB data remains after any call to recv, Windows Sockets notifies the application with FD_OOB or with exceptfds when using select.
  • For protocols where the OOB data has a position within the normal data stream, a single recv operation will not span that position. One recv will return the normal data before the "mark", and a second recv is required to begin reading data after the "mark".

With SO_OOBINLINE enabled:

  • FD_OOB messages are NOT posted for OOB data. OOB data is treated as normal for the purpose of the select and WSAAsyncSelect functions, and indicated by setting the socket in readfds or by sending an FD_READ message respectively.
  • The application can not call recv with the MSG_OOB flag set to read the OOB data block. The error code WSAEINVAL will be returned.
  • The application can call recv without the MSG_OOB flag set. Any OOB data will be delivered in its correct order within the "normal" data stream. OOB data will never be mixed with normal data. There must be three read requests to get past the OOB data. The first returns the normal data prior to the OOB data block, the second returns the OOB data, the third returns the normal data following the OOB data. In other words, the OOB data block boundaries are preserved.

The WSAAsyncSelect routine is particularly well suited to handling notification of the presence of out-of-band-data when SO_OOBINLINE is off.

OOB data in TCP

Important The following discussion of out-of-band (OOB) data, implemented using TCP Urgent data, follows the model used in the Berkeley software distribution. Users and implementors should be aware that there are, at present, two conflicting interpretations of RFC 793 (where the concept is introduced), and that the implementation of out-of-band data in the Berkeley Software Distribution (BSD) does not conform to the Host Requirements laid down in RFC 1122.

Specifically, the TCP urgent pointer in BSD points to the byte after the urgent data byte, and an RFC-compliant TCP urgent pointer points to the urgent data byte. As a result, if an application sends urgent data from a BSD-compatible implementation to an RFC-1122 compatible implementation, the receiver will read the wrong urgent data byte (it will read the byte located after the correct byte in the data stream as the urgent data byte).

To minimize interoperability problems, applications writers are advised not to use out-of-band data unless this is required to interoperate with an existing service. Windows Sockets suppliers are urged to document the out-of-band semantics (BSD or RFC 1122) that their product implements.

Arrival of a TCP segment with the "URG" (for urgent) flag set indicates the existence of a single byte of "OOB" data within the TCP data stream. The "OOB data block" is one byte in size. The urgent pointer is a positive offset from the current sequence number in the TCP header that indicates the location of the "OOB data block" (ambiguously, as noted above). It might, therefore, point to data that has not yet been received.

If SO_OOBINLINE is disabled (the default) when the TCP segment containing the byte pointed to by the urgent pointer arrives, the OOB data block (one byte) is removed from the data stream and buffered. If a subsequent TCP segment arrives with the urgent flag set (and a new urgent pointer), the OOB byte currently queued can be lost as it is replaced by the new OOB data block (as occurs in Berkeley Software Distribution). It is never replaced in the data stream, however.

With SO_OOBINLINE enabled, the urgent data remains in the data stream. As a result, the OOB data block is never lost when a new TCP segment arrives containing urgent data. The existing OOB data "mark" is updated to the new position.


Summary of Windows Sockets 2 Functions

The following tables summarize the functions included in Windows Sockets 2, separated into two groups: Berkeley-style functions, and Microsoft Windows-specific Extension functions that have been ratified as part of the Windows Sockets 2 specification. These tables do not include the Windows Sockets functions known that are used with Registration and Name Resolution.


Socket Functions

The Windows Sockets specification includes all the following Berkeley-style socket routines that were part of the Windows Sockets 1.1 API:

accept1 | An incoming connection is acknowledged and associated with an immediately created socket. The original socket is returned to the listening state.
bind | Assign a local name to an unnamed socket.
closesocket1 | Remove a socket from the per-process object reference table. Only blocks if SO_LINGER is set with a non-zero timeout on a blocking socket.
connect1 | Initiate a connection on the specified socket.
getpeername | Retrieve the name of the peer connected to the specified socket.
getsockname | Retrieve the local address to which the specified socket is bound.
getsockopt | Retrieve options associated with the specified socket.
htonl2 | Convert a 32-bit quantity from host byte order to network byte order.
htons2 | Convert a 16-bit quantity from host byte order to network byte order.
inet_addr2 | Converts a character string representing a number in the Internet standard ".'' notation to an Internet address value.
inet_ntoa2 | Converts an Internet address value to an ASCII string in ".'' notation i.e. "a.b.c.d''.
ioctlsocket | Provide control for sockets.
listen | Listen for incoming connections on a specified socket.
ntohl2 | Convert a 32-bit quantity from network byte order to host byte order.
ntohs2 | Convert a 16-bit quantity from network byte order to host byte order.
recv1 | Receive data from a connected or unconnected socket.
recvfrom1 | Receive data from either a connected or unconnected socket.
select1 | Perform synchronous I/O multiplexing.
send1 | Send data to a connected socket.
sendto1 | Send data to either a connected or unconnected socket.
setsockopt | Store options associated with the specified socket.
shutdown | Shut down part of a full-duplex connection.
socket | Create an endpoint for communication and return a socket descriptor.
1 The routine can block if acting on a blocking socket. 2 The routine is retained for backward compatibility with Windows Sockets 1.1, and should only be used for sockets created with AF_INET address family.


Microsoft Windows-specific Extension Functions

The Windows Sockets specification provides a number of extensions to the standard set of Berkeley Sockets routines. Principally, these extended functions allow message or function-based, asynchronous access to network events, as well as enable overlapped I/O. While use of this extended API set is not mandatory for socket-based programming (with the exception of WSAStartup and WSACleanup), it is recommended for conformance with the Microsoft Windows programming paradigm. For features introduced in Windows Sockets 2, please see New Concepts, Additions and Changes for Windows Sockets 2.

WSAAccept1 | An extended version of accept which allows for conditional acceptance and socket grouping.
WSAAsyncGetHostByAddr2 3 WSAAsyncGetHostByName2 3 WSAAsyncGetProtoByName2 3 WSAAsyncGetProtoByNumber2 3 WSAAsyncGetServByName2 3 WSAAsyncGetServByPort2 3 | A set of functions which provide asynchronous versions of the standard Berkeley getXbyY functions. For example, the WSAAsyncGetHostByName function provides an asynchronous, message-based implementation of the standard Berkeley gethostbyname function.
WSAAsyncSelect 3 | Perform asynchronous version of select
WSACancelAsyncRequest2 3 | Cancel an outstanding instance of a WSAAsyncGetXByY function.
WSACleanup | Sign off from the underlying Windows Sockets DLL.
WSACloseEvent | Destroys an event object.
WSAConnect1 | An extended version of connect which allows for exchange of connect data and QOS specification.
WSACreateEvent | Creates an event object.
WSADuplicateSocket | Allow an underlying socket to be shared by creating a virtual socket.
WSAEnumNetworkEvents | Discover occurrences of network events.
WSAEnumProtocols | Retrieve information about each available protocol.
WSAEventSelect | Associate network events with an event object.
WSAGetLastError 3 | Obtain details of last Windows Sockets error
WSAGetOverlappedResult | Get completion status of overlapped operation.
WSAGetQOSByName | Supply QOS parameters based on a well-known service name.
WSAHtonl | Extended version of htonl
WSAHtons | Extended version of htons
WSAIoctl1 | Overlapped-capable version of ioctl
WSAJoinLeaf1 | Add a multipoint leaf to a multipoint session
WSANtohl | Extended version of ntohl
WSANtohs | Extended version of ntohs
WSAProviderConfigChange | Receive notifications of service providers being installed/removed.
WSARecv1 | An extended version of recv which accommodates scatter/gather I/O, overlapped sockets and provides the flags parameter as IN OUT
WSARecvFrom1 | An extended version of recvfrom which accommodates scatter/gather I/O, overlapped sockets and provides the flags parameter as IN OUT
WSAResetEvent | Resets an event object.
WSASend1 | An extended version of send which accommodates scatter/gather I/O and overlapped sockets
WSASendTo1 | An extended version of sendto which accommodates scatter/gather I/O and overlapped sockets
WSASetEvent | Sets an event object.
WSASetLastError 3 | Set the error to be returned by a subsequent WSAGetLastError
WSASocket | An extended version of socket which takes a WSAPROTOCOL_INFO struct as input and allows overlapped sockets to be created. Also allows socket groups to be formed.
WSAStartup 3 | Initialize the underlying Windows Sockets DLL.
WSAWaitForMultipleEvents1 |  | Blocks on multiple event objects.
1 The routine can block if acting on a blocking socket. 2 The routine is always realized by the name resolution provider associated with the default TCP/IP service provider, if any. 3 The routine was originally a Windows Sockets 1.1 function


Registration and Name Resolution

Windows Sockets 2 includes a new set of API functions that standardize the way applications access and use the various network naming services. When using these new functions, Windows Sockets 2 applications need not be cognizant of the widely differing protocols associated with name services such as DNS, NIS, X.500, SAP, etc. To maintain full backward compatibility with Windows Sockets 1.1, all of the existing getXbyY and asynchronous WSAAsyncGetXbyY database lookup functions continue to be supported, but are implemented in the Windows Sockets service provider interface in terms of the new name resolution capabilities. For more information, see the getservbyname and getservbyport functions. Also, see Windows Sockets 1.1 Compatibile Name Resolution for TCP/IP.


Protocol-Independent Name Resolution

In developing a protocol-independent client/server application, there are two basic requirements that exist with respect to name resolution and registration:

  • The ability of the server half of the application (hereafter referred to as a service) to register its existence within (or become accessible to) one or more name spaces
  • The ability of the client application to find the service within a name space and obtain the required transport protocol and addressing information

For those accustomed to developing TCP/IP based applications, this may seem to involve little more than looking up a host address and then using an agreed upon port number. Other networking schemes, however, allow the location of the service, the protocol used for the service, and other attributes to be discovered at run-time. To accommodate the broad diversity of capabilities found in existing name services, the Windows Sockets 2 interface adopts the model described below.


Name Resolution Model

A name space refers to some capability to associate (as a minimum) the protocol and addressing attributes of a network service with one or more human-friendly names. Many name spaces are currently in wide use including the Internet's Domain Name System(DNS), the bindery and Netware Directory Services (NDS) from Novell, X.500, etc. These name spaces vary widely in how they are organized and implemented. Some of their properties are particularly important to understand from the perspective of Windows Sockets name resolution.

Types of Name Spaces

There are three different types of name spaces in which a service could be registered:

  • dynamic
  • static
  • persistent

Dynamic name spaces allow services to register with the name space on the fly, and for clients to discover the available services at run-time. Dynamic name spaces frequently rely on broadcasts to indicate the continued availability of a network service. Examples of dynamic name spaces include the SAP name space used within a Netware environment and the NBP name space used by Appletalk.

Static name spaces require all of the services to be registered ahead of time, i.e. when the name space is created. The DNS is an example of a static name space. Although there is a programmatic way to resolve names, there is no programmatic way to register names.

Persistent name spaces allow services to register with the name space on the fly. Unlike dynamic name spaces however, persistent name spaces retain the registration information in non-volatile storage where it remains until such time as the service requests that it be removed. Persistent name spaces are typified by directory services such as X.500 and the NDS (Netware Directory Service). These environments allow the adding, deleting, and modification of service properties. In addition, the service object representing the service within the directory service could have a variety of attributes associated with the service. The most important attribute for client applications is the service's addressing information.

Name Space Organization

Many name spaces are arranged hierarchically. Some, such as X.500 and NDS, allow unlimited nesting. Others allow services to be combined into a single level of hierarchy or "group." This is typically referred to as a workgroup. When constructing a query, it is often necessary to establish a context point within a name space hierarchy from which the search will begin.

Name Space Provider Architecture

Naturally, the programmatic interfaces used to query the various types of name spaces and to register information within a name space (if supported) differ widely. A name space provider is a locally-resident piece of software that knows how to map between Windows Sockets's name space SPI and some existing name space (which could be implemented locally or be accessed via the network). This is illustrated as follows:

Name Space Provider Architecture

Note that it is possible for a given name space, say DNS, to have more than one name space provider installed on a given machine.

As mentioned above, the generic term service refers to the server-half of a client/server application. In Windows Sockets, a service is associated with a service class, and each instance of a particular service has a service name which must be unique within the service class. Examples of service classes include FTP Server, SQL Server, XYZ Corp. Employee Info Server, etc. As the example attempts to illustrate, some service classes are "well known" while others are very unique and specific to a particular vertical application. In either case, every service class is represented by both a class name and a class ID. The class name does not necessarily need to be unique, but the class ID must be. Globally Unique Identifiers (GUIDs) are used to represent service class IDs. For well-known services, class names and class ID's (GUIDs) have been pre-allocated, and macros are available to convert between, for example, TCP port numbers (inhost-byte order) and the corresponding class ID GUIDs. For other services, the developer chooses the class name and uses the UUIDGEN.EXE utility to generate a GUID for the class ID.

The notion of a service class exists to allow a set of attributes to be established that are held in common by all instances of a particular service. This set of attributes is provided at the time the service class is defined to Windows Sockets, and is referred to as the service class schema information. When a service is installed and made available on a host machine, that service is considered instantiated, and its service name is used to distinguish a particular instance of the service from other instances which may be known to the name space.

Note that the installation of a service class only needs to occur on machines where the service executes, not on all of the clients which may utilize the service. Where possible, the WS2_32.DLL will provide service class schema information to a name space provider at the time an instantiation of a service is to be registered or a service query is initiated. The WS2_32.DLL does not, of course, store this information itself, but attempts to retrieve it from a name space provider that has indicated its ability to supply this data. Since there is no guarantee that the WS2_32.DLL will be able to supply the service class schema, name space providers that need this information must have a fallback mechanism to obtain it through name space-specific means.

As noted above, the Internet has adopted what can be termed a host-centric service model. Applications needing to locate the transport address of a service generally must first resolve the address of a specific host known to host the service. To this address they add in the well-known port number and thus create a complete transport address. To facilitate the resolution of host names, a special service class identifier has been pre-allocated (SVCID_HOSTNAME). A query that specifies SVCID_HOSTNAME as the service class and uses the host name the service instance name will, if the query is successful, return host address information.

In Windows Sockets 2, applications that are protocol-independent wish to avoid the need to comprehend the internal details of a transport address. Thus the need to first get a host address and then add in the port is problematic. To avoid this, queries may also include the well-known name of a particular service and the protocol over which the service operates, such as "ftp/tcp". In this case, a successful query will return a complete transport address for the specified service on the indicated host, and the application will not be required to "crack open" a sockaddr structure. This is described in more detail below.

The Internet's Domain Name System does not have a well-defined means to store service class schema information. As a result, DNS name space providers will only be able to accommodate well-known TCP/IP services for which a service class GUID has been preallocated. In practice this is not a serious limitation since service class GUIDs have been preallocated for the entire set of TCP and UDP ports, and macros are available to retrieve the GUID associated with any TCP or UDP port with the port expressed in host-byte order. Thus all of the familiar services such as ftp, telnet, whois, etc. are well supported.

Continuing with our service class example, instance names of the ftp service may be "alder.intel.com" or "rhino.microsoft.com" while an instance of the XYZ Corp. Employee Info Server might be named "XYZ Corp. Employee Info Server Version 3.5". In the first two cases, the combination of the service class GUID for ftp and the machine name (supplied as the service instance name) uniquely identify the desired service. In the third case, the host name where the service resides can be discovered at service query time, so the service instance name does not need to include a host name.


Summary of Name Resolution Functions

The name resolution functions can be grouped into three categories: Service installation, client queries, and helper functions (and macros). The sections that follow identify the functions in each category and briefly describe their intended use. Key data structures are also described.

Service Installation

  • WSAInstallServiceClass
  • WSARemoveServiceClass
  • WSASetService

When the required service class does not already exist, an application uses WSAInstallServiceClass to install a new service class by supplying a service class name, a GUID for the service class ID, and a series of WSANSCLASSINFO structures. These structures are each specific to a particular name space, and supply common values such as recommended TCP port numbers or Netware SAP Identifiers. A service class can be removed by calling WSARemoveServiceClass and supplying the GUID corresponding to the class ID.

Once a service class exists, specific instances of a service can be installed or removed via WSASetService. This function takes a WSAQUERYSET structure as an input parameter along with an operation code and operation flags. The operation code indicates whether the service is being installed or removed. The WSAQUERYSET structure provides all of the relevant information about the service including service class ID, service name (for this instance), applicable name space identifier and protocol information, and a set of transport addresses at which the service listens. Services should invoke WSASetService when they initialize in order to advertise their presence in dynamic name spaces.

Client Query

  • WSAEnumNameSpaceProviders
  • WSALookupServiceBegin
  • WSALookupServiceNext
  • WSALookupServiceEnd

The WSAEnumNameSpaceProviders function allows an application to discover which name spaces are accessible via Windows Sockets's name resolution facilities. It also allows an application to determine whether a given name space is supported by more than one name space provider, and to discover the provider ID for any particular name space provider. Using a provider ID, the application can restrict a query operation to a specified name space provider.

Windows Sockets' name space query operations involves a series of calls: WSALookupServiceBegin, followed by one or more calls to WSALookupServiceNext and ending with a call to WSALookupServiceEnd. WSALookupServiceBegin takes a WSAQUERYSET structure as input in order to define the query parameters along with a set of flags to provide additional control over the search operation. It returns a query handle which is used in the subsequent calls to WSALookupServiceNext and WSALookupServiceEnd.

The application invokes WSALookupServiceNext to obtain query results, with results supplied in an application-supplied WSAQUERYSET buffer. The application continues to call WSALookupServiceNext until the error code WSA_E_NO_MORE is returned indicating that all results have been retrieved. The search is then terminated by a call to WSALookupServiceEnd. The WSALookupServiceEnd function can also be used to cancel a currently pending WSALookupServiceNext when called from another thread.

In Windows Socket 2, conflicting error codes are defined for WSAENOMORE (10102) and WSA_E_NO_MORE (10110). The error code WSAENOMORE will be removed in a future version and only WSA_E_NO_MORE will remain. For Windows Socket 2, however, applications should check for both WSAENOMORE and WSA_E_NO_MORE for the widest possible compatibility with Name Space Providers that use either one.

Helper Functions

  • WSAGetServiceClassNameByClassId
  • WSAAddressToString
  • WSAStringToAddress
  • WSAGetServiceClassInfo

The name resolution helper functions include a function to retrieve a service class name given a service class ID, a pair of functions used to translate a transport address between a sockaddr struct and an ASCII string representation, a function to retrieve the service class schema information for a given service class, and a set of macros for mapping well known services to pre-allocated GUIDs.

The following macros from winsock2.h aid in mapping between well known service classes and these name spaces.

SVCID_TCP(Port)

SVCID_UDP(Port)

SVCID_NETWARE(Object Type)

 Given a port for TCP/IP or UDP/IP or the object type in the case of Netware, return the GUID (port number in host order)
IS_SVCID_TCP(GUID)
IS_SVCID_UDP(GUID)
IS_SVCID_NETWARE(GUID) 		Returns TRUE if the GUID is within the allowable range
SET_TCP_SVCID(GUID, port)
SET_UDP_SVCID(GUID, port) 		Initializes a GUID structure with the GUID equivalent for a TCP or UDP port number (port number must be in host order)
PORT_FROM_SVCID_TCP(GUID)

PORT_FROM_SVCID_UDP(GUID)

SAPID_FROM_SVCID_NETWARE(GUID)

 Returns the port or object type associated with the GUID (port number in host order)


Name Resolution Data Structures

There are several important data structures that are used extensively throughout the name resolution functions. These are described below.

Query-Related Data Structures

The WSAQUERYSET structure is used to form queries for WSALookupServiceBegin, and used to deliver query results for WSALookupServiceNext. It is a complex structure since it contains pointers to several other structures, some of which reference still other structures. The relationship between WSAQUERYSET and the structures it references is illustrated as follows:

WSAQUERYSET and Friends

Within the WSAQUERYSET structure, most of the fields are self explanatory, but some deserve additional explanation. The dwSize field must always be filled in with sizeof(WSAQUERYSET), as this is used by name space providers to detect and adapt to different versions of the WSAQUERYSET structure that may appear over time.

The dwOutputFlags field is used by a name space provider to provide additional information about query results. For details, see WSALookupServiceNext.

The WSAECOMPARATOR structure referenced by lpversion is used for both query constraint and results. For queries, the dwVersion field indicates the desired version of the service. The ecHow field is an enumerated type which 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 be no less than the value of dwVersion.

The interpretation of dwNameSpace and lpNSProviderId depends upon how the structure is being used and is described further in the individual function descriptions that utilize this structure.

The lpszContext field applies to hierarchical name spaces, and specifies the starting point of a query or the location within the hierarchy where the service resides. The general rules are:

  • A value of NULL, blank ("") will start the search at the default context.
  • A value of "\" starts the search at the top of the name space.
  • 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 name space specific. If dwNameSpace is NS_ALL, then only "" or "\" should be passed as the context since these are recognized by all name spaces.

The lpszQueryString field is used to supply additional, name space-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, since protocol values only have meaning within the context of an address family.

The array of CSADDR_INFO structure referenced by lpcsaBuffer contain all of the information needed to 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 fields 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

When a new service class is installed, a WSASERVICECLASSINFO structure must be prepared and supplied. This structure also consists of substructures which contain a series of parameters that apply to specific name spaces.

Class Info Data Structures

For each service class, there is a single WSASERVICECLASSINFO structure. Within the WSASERVICECLASSINFO structure, the service class' unique identifier is contained in lpServiceClassId, and an associated display string is referenced by lpServiceClassName. This is the string that will be returned by WSAGetServiceClassNameByClassId.

The lpClassInfos field in the WSASERVICECLASSINFO structure references an array of WSANSCLASSINFO structures, each of which supplies a named and typed parameter that applies to a specified name space. Examples of values for the lpszName field include: "SapId", "TcpPort", "UdpPort", etc. These strings are generally specific to the name space identified in dwNameSpace. Typical values for dwValueType might be REG_DWORD, REG_SZ, etc. The dwValueSize field 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 name space provider when WSAInstallServiceClass is invoked. Each individual name space provider then sifts through the list of WSANSCLASSINFO structures and retain the information applicable to it.


Windows Sockets 1.1 Compatibile Name Resolution for TCP/IP

Windows Sockets 1.1 defined a number of routines that were used for name resolution with TCP/IP (IP version 4) networks. These are customarily called the getXbyY functions and include the following:

gethostname
gethostbyaddr
gethostbyname
getprotobyname
getprotobynumber
getservbyname
getservbyport

Asynchronous versions of these functions were also defined:

WSAAsyncGetHostByAddr
WSAAsyncGetHostByName
WSAAsyncGetProtoByName
WSAAsyncGetProtoByNumber
WSAAsyncGetServByName
WSAAsyncGetServByPort

There are also two functions (now implemented in the WinSock 2 DLL) used to convert dotted Ipv4 internet address notation to and from string and binary representations, respectively:

inet_addr
inet_ntoa

All of these functions are specific to Ipv4 TCP/IP networks and developers of protocol-independent applications are discouraged from continuing to utilize these transport-specific functions. However, in order to retain strict backwards compatibility with Windows Sockets 1.1, all of the above functions continue to be supported as long as at least one name space provider is present that supports the AF_INET address family (these functions are not relevant to IP version 6, denoted by AF_INET6).

The WS2_32.DLL implements these compatibility functions in terms of the new, protocol-independent name resolution facilities using an appropriate sequence of WSALookupServiceBegin/Next/End function calls. The details of how the getXbyY functions are mapped to name resolution functions are provided below. The WS2_32.DLL handles the differences between the asynchronous and synchronous versions of the getXbyY functions, so only the implementation of the synchronous getXbyY functions are discussed.


Basic Approach for getxbyy

Most getXbyY functions are translated by the WS2_32.DLL to a WSAServiceLookupBegin/Next/End sequence that uses one of a set of special GUIDs as the service class. These GUIDs identify the type of getXbyYoperation that is being emulated. The query is constrained to those NSPs that support AF_INET. Whenever a getXbyY function returns a hostent or servent structure, the WS2_32.DLL will specify the LUP_RETURN_BLOB flag in WSALookupServiceBegin so that the desired information will be returned by the NSP. These structures must be modified slightly in that the pointers contained within must be replaced with offsets that are relative to the start of the blob's data. All values referenced by these pointer fields must, of course, be completely contained within the blob, and all strings are ASCII.


The getprotobyname and getprotobynumber functions

These functions are implemented within the WS2_32.DLL by consulting a local protocols database. They do not result in any name resolution query.


The getservbyname and getservbyport functions

The WSALookupServiceBegin query uses SVCID_INET_SERVICEBYNAME as the service class GUID. The lpszServiceInstanceName field references a string which indicates the service name or service port, and (optionally) the service protocol. The formatting of the string is illustrated as "ftp/tcp" or "21/tcp" or just "ftp". The string is not case sensitive. The slash mark, if present, separates the protocol identifier from the preceding part of the string. The WS2_32.DLL will specify LUP_RETURN_BLOB and the NSP will place a servent struct in the blob (using offsets instead of pointers as described above). NSPs should honor these other LUP_RETURN_* flags as well:

LUP_RETURN_NAME | return the s_name field from servent struct in lpszServiceInstanceName.
LUP_RETURN_TYPE | return canonical GUID in lpServiceClassId It is understood that a service identified either as "ftp" or "21" may in fact be on some other port according to locally established conventions. The s_port field of the servent structure should indicate where the service can be contacted in the local environment. The canonical GUID returned when LUP_RETURN_TYPE is set should be one of the predefined GUIDs from svcs.h that corresponds to the port number indicated in the servent structure.


The gethostbyname function

The WSALookupServiceBegin query uses SVCID_INET_HOSTADDRBYNAME as the service class GUID. The host name is supplied in lpszServiceInstanceName. The WS2_32.DLL specifies LUP_RETURN_BLOB and the NSP places a hostent struct in the blob (using offsets instead of pointers as described above). NSPs should honor these other LUP_RETURN_* flags as well:

LUP_RETURN_NAME | return the h_name field from hostent struct in lpszServiceInstanceName.
LUP_RETURN_ADDR | return addressing info from hostent in CSADDR_INFO structs, port information is defaulted to zero. Note that this routine does not resolve host names that consist of a dotted internet address.


The gethostbyaddr function

The WSALookupServiceBegin query uses SVCID_INET_HOSTNAMEBYADDR as the service class GUID. The host address is supplied in lpszServiceInstanceName as a dotted internet string (e.g. "192.9.200.120"). The WS2_32.DLL specifies LUP_RETURN_BLOB and the NSP places a hostent struct in the blob (using offsets instead of pointers as described above). NSPs should honor these other LUP_RETURN_* flags as well:

LUP_RETURN_NAME | return the h_name field from hostent struct in lpszServiceInstanceName.
LUP_RETURN_ADDR | return addressing info from hostent in CSADDR_INFO structs, port information is defaulted to zero.


The gethostname function

The WSALookupServiceBegin query uses SVCID_HOSTNAME as the service class GUID. If lpszServiceInstanceName is NULL or references a NULL string (that is . ""), the local host is to be resolved. Otherwise, a lookup on a specified host name shall occur. For the purposes of emulating gethostname the WS2_32.DLL will specify a null pointer for lpszServiceInstanceName, and specify LUP_RETURN_NAME so that the host name is returned in the lpszServiceInstanceName field. If an application uses this query and specifies LUP_RETURN_ADDR then the host address will be provided in a CSADDR_INFO struct. The LUP_RETURN_BLOB action is undefined for this query. Port information will be defaulted to zero unless the lpszQueryString references a service such as "ftp", in which case the complete transport address of the indicated service will be supplied.


Multipoint and Multicast Semantics

In considering how to support multipoint and multicast in Windows Sockets 2 a number of existing and proposed multipoint/multicast schemes (including IP-multicast, ATM point-to-multipoint connection, ST-II, T.120, H.320 (MCU), etc.) were examined. While common in some aspects, each is widely different in others. To enable a coherent discussion of the various schemes, it is valuable to first create a taxonomy that characterizes the essential attributes of each. For simplicity, the term "multipoint" will hereafter be used to represent both multipoint and multicast.


Multipoint Taxonomy

The taxonomy described in this section first distinguishes the control plane that concerns itself with the way a multipoint session is established, from the data plane that deals with the transfer of data amongst session participants.

In the control plane there are two distinct types of session establishment: rooted and non-rooted. In the case of rooted control, there exists a special participant, called c_root, that is different from the rest of the members of this multipoint session, each of which is called a c_leaf. The c_root must remain present for the whole duration of the multipoint session, as the session will be broken up in the absence of the c_root. The c_root usually initiates the multipoint session by setting up the connection to a c_leaf, or a number of c_leafs. The c_root may add more c_leafs, or (in some cases) a c_leaf can join the c_root at a later time. Examples of the rooted control plane can be found in ATM and ST-II.

For a non-rooted control plane, all the members belonging to a multipoint session are leaves, i.e., no special participant acting as a c_root exists. Each c_leaf needs to add itself to a pre-existing multipoint session that either is always available (as in the case of an IP multicast address), or has been set up through some out-of-band mechanism which is outside the scope of the Windows Sockets specification. Another way to look at this is that a c_root still exists, but can be considered to be in the network cloud as opposed to one of the participants. Because a control root still exists, a non-rooted control plane could also be considered to be implicitly rooted. Examples for this kind of implicitly rooted multipoint schemes are: a teleconferencing bridge, the IP multicast system, a Multipoint Control Unit (MCU) in a H.320 video conference, etc.

In the data plane, there are two types of data transfer styles: rooted and non-rooted. In a rooted data plane, a special participant called d_root exists. Data transfer only occurs between the d_root and the rest of the members of this multipoint session, each of which is referred to as a d_leaf. The traffic could be undsi-directional, or bi-directional. The data sent out from the d_root will be duplicated (if required) and delivered to every d_leaf, while the data from d_leafs will only go to the d_root. In the case of a rooted data plane, there is no traffic allowed among d_leafs. An example of a protocol that is rooted in the data plane is ST-II.

In a non-rooted data plane, all the participants are equal in the sense that any data they send will be delivered to all the other participants in the same multipoint session. Likewise each d_leaf node will be able to receive data from all other d_leafs, and in some cases, from other nodes which are not participating in the multipoint session as well. No special d_root node exists. IP-multicast is non-rooted in the data plane.

Note that the question of where data unit duplication occurs, or whether a shared single tree or multiple shortest-path trees are used for multipoint distribution are protocol issues, and are irrelevant to the interface the application would use to perform multipoint communications. Therefore these issues are not addressed either in this appendix or by the Windows Sockets interface.

The following table depicts the taxonomy described above and indicates how existing schemes fit into each of the categories. Note that there does not appear to be any existing schemes that employ a non-rooted control plane along with a rooted data plane.

 | rooted control plane | non-rooted (implicit rooted) control plane
rooted data plane | ATM, ST-II | No known examples.
non-rooted data plane | T.120 | IP-multicast, H.320 (MCU)


WinSock 2 Interface Elements for Multipoint and Multicast

Windows Sockets 2 Interface Elements for Multipoint and Multicast

The mechanisms that have been incorporated into Windows Sockets 2 for utilizing multipoint capabilities can be summarized as follows:

Three attribute bits in the WSAPROTOCOL_INFO struct

  1. Four flags defined for the dwFlags parameter of WSASocket
  2. One function, WSAJoinLeaf, for adding leaf nodes into a multipoint session
  3. Two WSAIoctl command codes for controlling multipoint loopback and the scope of multicast transmissions.

The paragraphs which follow describe these interface elements in more detail.


Attributes in WSAPROTOCOL_INFO struct

In support of the taxonomy described above, three attribute fields in the WSAPROTOCOL_INFO structure are use to distinguish the different schemes used in the control and data planes respectively:

  1. XP1_SUPPORT_MULTIPOINT with a value of 1 indicates this protocol entry supports multipoint communications, and that the following two fields are meaningful.
  2. XP1_MULTIPOINT_CONTROL_PLANE indicates whether the control plane is rooted (value = 1) or non-rooted (value = 0).
  3. XP1_MULTIPOINT_DATA_PLANE indicates whether the data plane is rooted (value = 1) or non-rooted (value = 0).

Note that two WSAPROTOCOL_INFO entries would be present if a multipoint protocol supported both rooted and non-rooted data planes, one entry for each.

The application can use WSAEnumProtocols to discover whether multipoint communications is supported for a given protocol and, if so, how it is supported with respect to the control and data planes, respectively.

Flag bits for WSASocket

In some instances sockets joined to a multipoint session may have some behavioral differences from point-to-point sockets. For example, a d_leaf socket in a rooted data plane scheme can only send information to the d_root participant. This creates a need for the application to be able to indicated the intended use of a socket coincident with its creation. This is done through four flag bits that can be set in the dwFlags parameter to WSASocket:

  • WSA_FLAG_MULTIPOINT_C_ROOT, for the creation of a socket acting as a c_root, and only allowed if a rooted control plane is indicated in the corresponding WSAPROTOCOL_INFO entry.
  • WSA_FLAG_MULTIPOINT_C_LEAF, for the creation of a socket acting as a c_leaf, and only allowed if XP1_SUPPORT_MULTIPOINT is indicated in the corresponding WSAPROTOCOL_INFO entry.
  • WSA_FLAG_MULTIPOINT_D_ROOT, for the creation of a socket acting as a d_root, and only allowed if a rooted data plane is indicated in the corresponding WSAPROTOCOL_INFO entry.
  • WSA_FLAG_MULTIPOINT_D_LEAF, for the creation of a socket acting as a d_leaf, and only allowed if XP1_SUPPORT_MULTIPOINT is indicated in the corresponding WSAPROTOCOL_INFO entry.

Note that when creating a multipoint socket, exactly one of the two control plane flags, and one of the two data plane flags must be set in WSASocket's dwFlags parameter. Thus, the four possibilities for creating multipoint sockets are: "c_root/d_root", "c_root/d_leaf", "c_leaf/d_root", or "c_leaf /d_leaf".

SIO_MULTIPOINT_LOOPBACK command code for WSAIoctl

When d_leaf sockets are used in a non-rooted data plane, it is generally desirable to be able to control whether traffic sent out is also received back on the same socket. The SIO_MULTIPOINT_LOOPBACK command code for WSAIoctl is used to enable or disable loopback of multipoint traffic.

SIO_MULTICAST_SCOPE command code for WSAIoctl

When multicasting is employed, it is usually necessary to specify the scope over which the multicast should occur. Scope is defined as the number of routed network segments to be covered. A scope of zero would indicate that the multicast transmission would not be placed "on the wire" but could be disseminated across sockets within the local host. A scope value of one (the default) indicates that the transmission will be placed on the wire, but will not cross any routers. Higher scope values determine the number of routers that may be crossed. Note that this corresponds to the time-to-live (TTL) parameter in IP multicasting.

The function WSAJoinLeaf is used to join a leaf node into the multipoint session. See below for a discussion on how this function is utilized.


Semantics for joining multipoint leaves

In the following, a multipoint socket is frequently described by defining its role in one of the two planes (control or data). It should be understood that this same socket has a role in the other plane, but this is not mentioned in order to keep the references short. For example when a reference is made to a "c_root socket", this could be either a c_root/d_root or a c_root/d_leaf socket.

In rooted control plane schemes, new leaf nodes are added to a multipoint session in one or both of two different ways. In the first method, the root uses WSAJoinLeaf to initiate a connection with a leaf node and invite it to become a participant. On the leaf node, the peer application must have created a c_leaf socket and used listen to set it into listen mode. The leaf node will receive an FD_ACCEPT indication when invited to join the session, and signals its willingness to join by calling WSAAccept. The root application will receive an FD_CONNECT indication when the join operation has been completed.

In the second method, the roles are essentially reversed. The root application creates a c_root socket and sets it into listen mode. A leaf node wishing to join the session creates a c_leaf socket and uses WSAJoinLeaf to initiate the connection and request admittance. The root application receives FD_ACCEPT when an incoming admittance request arrives, and admits the leaf node by calling WSAAccept. The leaf node receives FD_CONNECT when it has been admitted.

In a non-rooted control plane, where all nodes are c_leaf's, the WSAJoinLeaf is used to initiate the inclusion of a node into an existing multipoint session. An FD_CONNECT indication is provided when the join has been completed and the returned socket descriptor is useable in the multipoint session. In the case of IP multicast, this would correspond to the IP_ADD_MEMBERSHIP socket option.

(Readers familiar with IP multicast's use of the connectionless UDP protocol may be concerned by the connection-oriented semantics presented here. In particular the notion of using WSAJoinLeaf on a UDP socket and waiting for an FD_CONNECT indication may be troubling. There is, however, ample precedent for applying connection-oriented semantics to connectionless protocols. It is allowed and sometime useful, for example, to invoke the standard connect function on a UDP socket. The general result of applying connection-oriented semantics to connectionless sockets is a restriction in how such sockets may be used, and such is the case here as well. A UDP socket used in WSAJoinLeaf will have certain restrictions, and waiting for an FD_CONNECT indication (which in this case simply indicates that the corresponding IGMP message has been sent) is one such limitation.)

There are, therefore, three instances where an application would use WSAJoinLeaf:

  1. Acting as a multipoint root and inviting a new leaf to join the session
  2. Acting as a leaf making an admittance request to a rooted multipoint session
  3. Acting as a leaf seeking admittance to a non-rooted multipoint session (e.g. IP multicast)

Using WSAJoinLeaf

As mentioned previously, the function WSAJoinLeaf is used to join a leaf node into a multipoint session. WSAJoinLeaf has the same parameters and semantics as WSAConnect except that it returns a socket descriptor (as in WSAAccept), and it has an additional dwFlags parameter. The dwFlags parameter is used to indicate whether the socket will be acting only as a sender, only as a receiver, or both. Only multipoint sockets may be used for input parameter s in this function. If the multipoint socket is in the non-blocking mode, the returned socket descriptor will not be useable until after a corresponding FD_CONNECT indication has been received. A root application in a multipoint session may call WSAJoinLeaf one or more times in order to add a number of leaf nodes, however at most one multipoint connection request may be outstanding at a time.

The socket descriptor returned by WSAJoinLeaf is different depending on whether the input socket descriptor, s, is a c_root or a c_leaf. When used with a c_root socket, the name parameter designates a particular leaf node to be added and the returned socket descriptor is a c_leaf socket corresponding to the newly added leaf node. It is not intended to be used for exchange of multipoint data, but rather is used to receive FD_XXX indications (e.g. FD_CLOSE) for the connection that exists to the particular c_leaf. Some multipoint implementations may also allow this socket to be used for "side chats" between the root and an individual leaf node. An FD_CLOSE indication will be received for this socket if the corresponding leaf node calls closesocket to drop out of the multipoint session. Symmetrically, invoking closesocket on the c_leaf socket returned from WSAJoinLeaf will cause the socket in the corresponding leaf node to get FD_CLOSE notification.

When WSAJoinLeaf is invoked with a c_leaf socket, the name parameter contains the address of the root application (for a rooted control scheme) or an existing multipoint session (non-rooted control scheme), and the returned socket descriptor is the same as the input socket descriptor. In a rooted control scheme, the root application would put its c_root socket in the listening mode by calling listen. The standard FD_ACCEPT notification will be delivered when the leaf node requests to join itself to the multipoint session. The root application uses the usual accept /WSAAccept functions to admit the new leaf node. The value returned from either accept or WSAAccept is also a c_leaf socket descriptor just like those returned from WSAJoinLeaf. To accommodate multipoint schemes that allow both root-initiated and leaf-initiated joins, it is acceptable for a c_root socket that is already in listening mode to be used as in input to WSAJoinLeaf.

A multipoint root application is generally responsible for the orderly dismantling of a multipoint session. Such an application may use shutdown or closesocket on a c_root socket to cause all of the associated c_leaf sockets, including those returned from WSAJoinLeaf and their corresponding c_leaf sockets in the remote leaf nodes, to get FD_CLOSE notification.


Semantic differences between multipoint sockets and regular sockets

In the control plane, there are some significant semantic differences between a c_root socket and a regular point-to-point socket:

  1. the c_root socket can be used in WSAJoinLeaf to join a new a leaf;
  2. placing a c_root socket into the listening mode (by callings listen) does not preclude the c_root socket from being used in a call to WSAJoinLeaf to add a new leaf, or for sending and receiving multipoint data;
  3. the closing of a c_root socket will cause all the associated c_leaf sockets to get FD_CLOSE notification.

There is no semantic differences between a c_leaf socket and a regular socket in the control plane, except that the c_leaf socket can be used in WSAJoinLeaf, and the use of c_leaf socket in listen indicates that only multipoint connection requests should be accepted.

In the data plane, the semantic differences between the d_root socket and a regular point-to-point socket are

  1. the data sent on the d_root socket will be delivered to all the leaves in the same multipoint session;
  2. the data received on the d_root socket may be from any of the leaves.

The d_leaf socket in the rooted data plane has no semantic difference from the regular socket, however, in the non-rooted data plane, the data sent on the d_leaf socket will go to all the other leaf nodes, and the data received could be from any other leaf nodes. As mentioned earlier, the information about whether the d_leaf socket is in a rooted or non-rooted data plane is contained in the corresponding WSAPROTOCOL_INFO structure for the socket.


How existing multipoint protocols support these extensions

In this section we indicate how IP multicast and ATM point-to-multipoint capabilities would be accessed via the Windows Sockets 2 multipoint functions. We chose these two as examples because they are very popular and well understood.


IP multicast

IP multicast falls into the category of non-rooted data plane and non-rooted control plane. All applications play a leaf role. Currently most IP multicast implementations use a set of socket options proposed by Steve Deering to the IETF. Five operations are made thus available:

  • IP_MULTICAST_TTL - set time to live, controls scope of multicast session
  • IP_MULTICAST_IF - determine interface to be used for multicasting
  • IP_ADD_MEMBERSHIP - join a specified multicast session
  • IP_DROP_MEMBERSHIP - drop out of a multicast session
  • IP_MULTICAST_LOOP - control loopback of multicast traffic

Setting the time-to-live for an IP multicast socket maps directly to using the SIO_MULTICAST_SCOPE command code for WSAIoctl. The method for determining the IP interface to be used for multicasting is via a TCP/IP-specific socket option as described in the Windows Sockets 2 Protocol Specific Annex.

The remaining three operations are covered well with the Windows Sockets 2 semantics described here. The application would open sockets with c_leaf/d_leaf flags in WSASocket. It would use WSAJoinLeaf to add itself to a multicast group on the default interface designated for multicast operations. If the flag in WSAJoinLeaf indicates that this socket is only a sender, then the join operation is essentially a no-op and no IGMP messages need to be sent. Otherwise, an IGMP packet is sent out to the router to indicate interests in receiving packets sent to the specified multicast address. Since the application created special c_leaf/d_leaf sockets used only for performing multicast, the standard closesocket function would be used to drop out of the multicast session. The SIO_MULTIPOINT_LOOPBACK command code for WSAIoctl provides a generic control mechanism for determining whether data sent on a d_leaf socket in a non-rooted multipoint scheme will be also received on the same socket.


ATM Point to Multipoint

ATM falls into the category of rooted data and rooted control planes. An application acting as the root would create c_root sockets and counterparts running on leaf nodes would utilize c_leaf sockets. The root application will use WSAJoinLeaf to add new leaf nodes. The corresponding applications on the leaf nodes will have set their c_leaf sockets into listen mode. WSAJoinLeaf with a c_root socket specified will be mapped to the Q.2931 ADDPARTY message. The leaf-initiated join is not supported in ATM UNI 3.1, but will be supported in ATM UNI 4.0. Thus WSAJoinLeaf with a c_leaf socket specified will be mapped to the appropriate ATM UNI 4.0 message.


Additional Windows Socket Information

This section contains information on the Windows Sockets 2 header file, additional Windows Sockets reference material, and the error codes encountered in programming for Windows Sockets 2.


Windows Sockets 2 Header File - WINSOCK2.H

New versions of WINSOCK2.H will appear periodically as new identifiers are allocated by the Windows Sockets Identifier Clearinghouse. The clearinghouse can be reached via the world wide web at

http://www.stardust.com/wsresource/winsock2/ws2ident.html


Socket Options Specific to Microsoft's Service Providers

Microsoft's service providers support addtional socket options not included in the Windows Sockets 2 API.


Socket Option for NT 4.0 Only

The following socket options are Microsoft-specific extensions for connect and disconnect data and options and are used only by non-TCP/IP transports such as DECNet, OSI TP4, etc. These are only used in Microsoft's implementation of Windows Sockets on NT 4.0.

SO_CONNDATA

SO_CONNOPT

SO_DISCDATA

SO_DISCOPT

SO_CONNDATALEN

SO_CONNOPTLEN

SO_DISCDATALEN

SO_DISCOPTLEN

The following socket options are Microsoft-specific extensions for controlling the size of datagrams:

SO_MAXDG

SO_MAXPATHDG


Socket Option for NT 4.0 and Win95

SO_SNDTIMEO

SO_RCVTIMEO

Details on SO_SNDTIMEO and SO_RCVTIMEO

These two options set up timeouts for the send, sendto, recv, and recvfrom functions. You can obtain the same functionality by calling select with a timeout just before the I/O call, but these options offer a significant improvement in performance by avoiding a kernel transition and the other overhead of the select call. For any code whose performance is very critical, applications should use these timeout options rather than select.

You can set these options on any type of socket in any state. The default value for these options is zero, which refers to an infinite timeout. Any other setting is the timeout, in milliseconds. It is valid to set the timeout to any value, but values less than 500 milliseconds (half a second) are interpreted to be 500 milliseconds.

To set a send timeout, use

int timeout = TIMEOUT_VALUE;
int err;
SOCKET s;

s = socket( ... );
err = setsockopt(
        s,
        SOL_SOCKET,
        SO_SNDTIMEO,
        (char *)&timeout,
        sizeof(timeout));
if (err != NO_ERROR) {
    /* failed for some reason... */
}

The TIMEOUT_VALUE is the needed timeout in milliseconds. To set a receive timeout, substitute SO_RCVTIMEO for SO_SNDTIMEO in the preceding example.

After setting one of these options to a nonzero value, I/O through the Windows Sockets calls fails with the error WSAETIMEDOUT if the request cannot be satisfied within the specified timeout. If a request times out, an application has no guarantees as to how much data was actually sent or received in the I/O call.

The following socket option is used in conjunction with the MS Extension function AcceptEx.

SO_UPDATE_ACCEPT_CONTEXT


Additional Documentation

This specification is intended to cover the Windows Sockets interface in detail. Many details of specific protocols and Windows, however, are intentionally omitted in the interest of brevity, and this specification often assumes background knowledge of these topics. For more information, the following references may be helpful:

Networking Books

Braden, R.[1989], RFC 1122, Requirements for Internet Hosts--Communication Layers, Internet Engineering Task Force.

Comer, D. [1991], Internetworking with TCP/IP Volume I: Principles, Protocols, and Architecture, Prentice Hall, Englewood Cliffs, New Jersey.

Comer, D. and Stevens, D. [1991], Internetworking with TCP/IP Volume II: Design, Implementation, and Internals, Prentice Hall, Englewood Cliffs, New Jersey.

Comer, D. and Stevens, D. [1991], Internetworking with TCP/IP Volume III: Client-Server Programming and Applications, Prentice Hall, Englewood Cliffs, New Jersey.

Leffler, S. et al., An Advanced 4.3BSD Interprocess Communication Tutorial.

Stevens, W.R. [1990], Unix Network Programming, Prentice Hall, Englewood Cliffs, New Jersey.

Stevens, W.R. [1994]. TCP/IP Illustrated, Volume 1: The Protocols, Addison-Wesley, Massachusetts

Wright, G.R. and Stevens, W.R. [1995], TCP/IP Illustrated Volume 2: The Implementation, Addison-Wesley., Massachusetts

Windows Sockets Books

Bonner, P. [1995], Network Programming with Windows Sockets, ISBN: 0-13-230152-0, Prentice Hall, Englewood Cliffs, New Jersey.

Dumas, A. [1995], Programming Windows Sockets, ISBN: 0-672-30594-1, Sams Publishing, Indianapolis, Indiana

Quinn, B. and Shute, D. [1995], Windows Sockets Network Programming, ISBN: 0-201-63372-8, Addison-Wesley Publishing Company, Reading, Massachusetts

Roberts, D. [1995], Developing for the Internet with Winsock, ISBN 1-883577-42-X, Coriolis Group Books.


Error Codes

The following is a list of possible error codes returned by the WSAGetLastError call, along with their extended explanations. Errors are listed in alphabetical order by error macro. Some error codes defined in WINSOCK2.H are not returned from any function - these have not been listed here.

WSAEACCES
(10013)
Permission denied.
An attempt was made to access a socket in a way forbidden by its access permissions. An example is using a broadcast address for sendto without broadcast permission being set using setsockopt(SO_BROADCAST).
WSAEADDRINUSE
(10048)
Address already in use.
Only one usage of each socket address (protocol/IP address/port) is normally permitted. This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that wasn't closed properly, or one that is still in the process of closing. For server applications that need to bind multiple sockets to the same port number, consider using setsockopt (SO_REUSEADDR). Client applications usually need not call bind at all - connect will choose an unused port automatically. When bind is called with a wild-card address (involving ADDR_ANY), a WSAEADDRINUSE error could be delayed until the specific address is "committed." This could happen with a call to other function later, including connect, listen, WSAConnect or WSAJoinLeaf.
WSAEADDRNOTAVAIL
(10049)
Cannot assign requested address.
The requested address is not valid in its context. Normally results from an attempt to bind to an address that is not valid for the local machine. This can also result from connect, sendto, WSAConnect, WSAJoinLeaf, or WSASendTo when the remote address or port is not valid for a remote machine (e.g. address or port 0).
WSAEAFNOSUPPORT
(10047)
Address family not supported by protocol family.
An address incompatible with the requested protocol was used. All sockets are created with an associated "address family" (i.e. AF_INET for Internet Protocols) and a generic protocol type (i.e. SOCK_STREAM). This error will be returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, e.g. in sendto.
WSAEALREADY
(10037)
Operation already in progress.
An operation was attempted on a non-blocking socket that already had an operation in progress - i.e. calling connect a second time on a non-blocking socket that is already connecting, or canceling an asynchronous request (WSAAsyncGetXbyY) that has already been canceled or completed.
WSAECONNABORTED
(10053)
Software caused connection abort.
An established connection was aborted by the software in your host machine, possibly due to a data transmission timeout or protocol error.
WSAECONNREFUSED
(10061)
Connection refused.
No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host - i.e. one with no server application running.
WSAECONNRESET
(10054)
Connection reset by peer.
A existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, or the remote host used a "hard close" (see setsockopt for more information on the SO_LINGER option on the remote socket.) This error may also result if a connection was broken due to "keep-alive" activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
WSAEDESTADDRREQ
(10039)
Destination address required.
A required address was omitted from an operation on a socket. For example, this error will be returned if sendto is called with the remote address of ADDR_ANY.
WSAEFAULT
(10014)
Bad address.
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument which is a struct sockaddr is smaller than sizeof(struct sockaddr).
WSAEHOSTDOWN
(10064)
Host is down.
A socket operation failed because the destination host was down. A socket operation encountered a dead host. Networking activity on the local host has not been initiated. These conditions are more likely to be indicated by the error WSAETIMEDOUT.
WSAEHOSTUNREACH
(10065)
No route to host.
A socket operation was attempted to an unreachable host. See WSAENETUNREACH
WSAEINPROGRESS
(10036)
Operation now in progress.
A blocking operation is currently executing. Windows Sockets only allows a single blocking operation to be outstanding per task (or thread), and if any other function call is made (whether or not it references that or any other socket) the function fails with the WSAEINPROGRESS error.
WSAEINTR
(10004)
Interrupted function call.
A blocking operation was interrupted by a call to WSACancelBlockingCall.
WSAEINVAL
(10022)
Invalid argument.
Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function). In some instances, it also refers to the current state of the socket - for instance, calling accept on a socket that is not listening.
WSAEISCONN
(10056)
Socket is already connected.
A connect request was made on an already connected socket. Some implementations also return this error if sendto is called on a connected SOCK_DGRAM socket (For SOCK_STREAM sockets, the to parameter in sendto is ignored), although other implementations treat this as a legal occurrence.
WSAEMFILE
(10024)
Too many open files.
Too many open sockets. Each implementation may have a maximum number of socket handles available, either globally, per process or per thread.
WSAEMSGSIZE
(10040)
Message too long.
A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself.
WSAENETDOWN
(10050)
Network is down.
A socket operation encountered a dead network. This could indicate a serious failure of the network system (i.e. the protocol stack that the WinSock DLL runs over), the network interface, or the local network itself.
WSAENETRESET
(10052)
Network dropped connection on reset.
The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress. It can also be returned by setsockopt if an attempt is made to set SO_KEEPALIVE on a connection that has already failed.
WSAENETUNREACH
(10051)
Network is unreachable.
A socket operation was attempted to an unreachable network. This usually means the local software knows no route to reach the remote host.
WSAENOBUFS
(10055)
No buffer space available.
An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
WSAENOPROTOOPT
(10042)
Bad protocol option.
An unknown, invalid or unsupported option or level was specified in a getsockopt or setsockopt call.
WSAENOTCONN
(10057)
Socket is not connected.
A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using sendto) no address was supplied. Any other type of operation might also return this error - for example, setsockopt setting SO_KEEPALIVE if the connection has been reset.
WSAENOTSOCK
(10038)
Socket operation on non-socket.
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.
WSAEOPNOTSUPP
(10045)
Operation not supported.
The attempted operation is not supported for the type of object referenced. Usually this occurs when a socket descriptor to a socket that cannot support this operation, for example, trying to accept a connection on a datagram socket.
WSAEPFNOSUPPORT
(10046)
Protocol family not supported.
The protocol family has not been configured into the system or no implementation for it exists. Has a slightly different meaning to WSAEAFNOSUPPORT, but is interchangeable in most cases, and all Windows Sockets functions that return one of these specify WSAEAFNOSUPPORT.
WSAEPROCLIM
(10067)
Too many processes.
A Windows Sockets implementation may have a limit on the number of applications that may use it simultaneously. WSAStartup may fail with this error if the limit has been reached.
WSAEPROTONOSUPPORT
(10043)
Protocol not supported.
The requested protocol has not been configured into the system, or no implementation for it exists. For example, a socket call requests a SOCK_DGRAM socket, but specifies a stream protocol.
WSAEPROTOTYPE
(10041)
Protocol wrong type for socket.
A protocol was specified in the socket function call that does not support the semantics of the socket type requested. For example, the ARPA Internet UDP protocol cannot be specified with a socket type of SOCK_STREAM.
WSAESHUTDOWN
(10058)
Cannot send after socket shutdown.
A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call. By calling shutdown a partial close of a socket is requested, which is a signal that sending or receiving or both has been discontinued.
WSAESOCKTNOSUPPORT
(10044)
Socket type not supported.
The support for the specified socket type does not exist in this address family. For example, the optional type SOCK_RAW might be selected in a socket call, and the implementation does not support SOCK_RAW sockets at all.
WSAETIMEDOUT
(10060)
Connection timed out.
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
WSATYPE_NOT_FOUND
(10109)
Class type not found.
The specified class was not found.
WSAEWOULDBLOCK
(10035)
Resource temporarily unavailable.
This error is returned from operations on non-blocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket. It is a non-fatal error, and the operation should be retried later. It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a non-blocking SOCK_STREAM socket, since some time must elapse for the connection to be established.
WSAHOST_NOT_FOUND
(11001)
Host not found.
No such host is known. The name is not an official hostname or alias, or it cannot be found in the database(s) being queried. This error may also be returned for protocol and service queries, and means the specified name could not be found in the relevant database.
WSA_INVALID_HANDLE
(OS dependent)
Specified event object handle is invalid.
An application attempts to use an event object, but the specified handle is not valid.
WSA_INVALID_PARAMETER
(OS dependent)
One or more parameters are invalid.
An application used a Windows Sockets function which directly maps to a Win32 function. The Win32 function is indicating a problem with one or more parameters.
WSAINVALIDPROCTABLE
(OS dependent)
Invalid procedure table from service provider.
A service provider returned a bogus proc table to WS2_32.DLL. (Usually caused by one or more of the function pointers being NULL.)
WSAINVALIDPROVIDER
(OS dependent)
Invalid service provider version number.
A service provider returned a version number other than 2.0.
WSA_IO_INCOMPLETE
(OS dependent)
Overlapped I/O event object not in signaled state.
The application has tried to determine the status of an overlapped operation which is not yet completed. Applications that use WSAGetOverlappedResult (with the fWait flag set to false) in a polling mode to determine when an overlapped operation has completed will get this error code until the operation is complete.
WSA_IO_PENDING
(OS dependent)
Overlapped operations will complete later.
The application has initiated an overlapped operation which cannot be completed immediately. A completion indication will be given at a later time when the operation has been completed.
WSA_NOT_ENOUGH_MEMORY
(OS dependent)
Insufficient memory available.
An application used a Windows Sockets function which directly maps to a Win32 function. The Win32 function is indicating a lack of required memory resources.
WSANOTINITIALISED
(10093)
Successful WSAStartup not yet performed.
Either the application hasn't called WSAStartup or WSAStartup failed. The application may be accessing a socket which the current active task does not own (i.e. trying to share a socket between tasks), or WSACleanup has been called too many times.
WSANO_DATA
(11004)
Valid name, no data record of requested type.
The requested name is valid and was found in the database, but it does not have the correct associated data being resolved for. The usual example for this is a hostname -> address translation attempt (using gethostbyname or WSAAsyncGetHostByName) which uses the DNS (Domain Name Server), and an MX record is returned but no A record - indicating the host itself exists, but is not directly reachable.
WSANO_RECOVERY
(11003)
This is a non-recoverable error.
This indicates some sort of non-recoverable error occurred during a database lookup. This may be because the database files (e.g. BSD-compatible HOSTS, SERVICES or PROTOCOLS files) could not be found, or a DNS request was returned by the server with a severe error.
WSAPROVIDERFAILEDINIT
(OS dependent)
Unable to initialize a service provider.
Either a service provider's DLL could not be loaded (LoadLibrary failed) or the provider's WSPStartup/NSPStartup function failed.
WSASYSCALLFAILURE
(OS dependent)
System call failure.
Returned when a system call that should never fail does. For example, if a call to WaitForMultipleObjects fails or one of the registry functions fails trying to manipulate theprotocol/namespace catalogs.
WSASYSNOTREADY
(10091)
Network subsystem is unavailable.
This error is returned by WSAStartup if the Windows Sockets implementation cannot function at this time because the underlying system it uses to provide network services is currently unavailable. Users should check:
  • that the appropriate Windows Sockets DLL file is in the current path,
  • that they are not trying to use more than one Windows Sockets implementation simultaneously. If there is more than one WINSOCK DLL on your system, be sure the first one in the path is appropriate for the network subsystem currently loaded.
  • the Windows Sockets implementation documentation to be sure all necessary components are currently installed and configured correctly.
WSATRY_AGAIN
(11002)
Non-authoritative host not found.
This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. A retry at some time later may be successful.
WSAVERNOTSUPPORTED
(10092)
WINSOCK.DLL version out of range.
The current Windows Sockets implementation does not support the Windows Sockets specification version requested by the application. Check that no old Windows Sockets DLL files are being accessed.
WSAEDISCON
(10094)
Graceful shutdown in progress.
Returned by WSARecv and WSARecvFrom to indicate the remote party has initiated a graceful shutdown sequence.
WSA_OPERATION_ABORTED
(OS dependent)
Overlapped operation aborted.
An overlapped operation was canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl.


accept

The Windows Sockets accept function accepts an incoming connection attempt on a socket.

SOCKET accept (
  SOCKET s,
  struct sockaddr FAR* addr,
  int FAR* addrlen
);

Parameters

s
[in] A descriptor identifying a socket that has been placed in a listening state with the listen function. The connection will actually be made with the socket that is returned by accept.
addr
[out] An optional pointer to a buffer that receives the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family established when the socket was created.
addrlen
[out] An optional pointer to an integer that contains the length of the address addr.

Remarks

The accept function extracts the first connection on the queue of pending connections on socket s. It then creates a new socket and returns a handle to the new socket. The newly created socket is the socket that will handle the actual the connection and has the same properties as socket s, including the asynchronous events registered with the WSAAsyncSelect or WSAEventSelect functions. The socket s does not have the listening socket's group ID, if any was applied.

The accept function can block the caller until a connection is present if no pending connections are present on the queue, and the socket is marked as blocking. If the socket is marked nonblocking and no pending connections are present on the queue, accept returns an error as described below. After the successful completion of accept returns a new socket handle, the accepted socket cannot be used to accept more connections. The original socket remains open and listens for new connection requests.

The parameter addr is a result parameter that is filled in with the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family in which the communication is occurring. The addrlen is a value-result parameter; it should initially contain the amount of space pointed to by addr; on return it will contain the actual length (in bytes) of the address returned.

The accept function is used with connection-oriented socket types such as SOCK_STREAM.

If addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned.

Windows CE: Windows CE does not support the WSAEINTR error value.

For IrSocket implementation, the addr and addrlen parameters should always be NULL.

Return Values

If no error occurs, accept returns a value of type SOCKET that is a descriptor for the new socket. This returned value is a handle for the socket on which the actual connection will be made.

Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.

The integer referred to by addrlen initially contains the amount of space pointed to by addr. On return it will contain the actual length in bytes of the address returned.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this FUNCTION.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The addrlen parameter is too small or addr is not a valid part of the user address space.
WSAEINTR | A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | The listen function was not invoked prior to accept.
WSAEMFILE | The queue is nonempty upon entry to accept and there are no descriptors available.
WSAENOBUFS | No buffer space is available.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The referenced socket is not a type that supports connection-oriented service.
WSAEWOULDBLOCK | The socket is marked as nonblocking and no connections are present to be accepted.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

bind, connect, listen, select, socket, WSAAsyncSelect, WSAAccept


AcceptEx

Notice This function is a Microsoft-specific extension to the Windows Sockets specification. For more information, see Microsoft Extensions and Windows Sockets 2.

The Windows Sockets AcceptEx function accepts a new connection, returns the local and remote address, and receives the first block of data sent by the client application.

BOOL AcceptEx (
  SOCKET sListenSocket,
  SOCKET sAcceptSocket,
  PVOID lpOutputBuffer,
  DWORD dwReceiveDataLength,
  DWORD dwLocalAddressLength,
  DWORD dwRemoteAddressLength,
  LPDWORD lpdwBytesReceived,
  LPOVERLAPPED lpOverlapped
);

Parameters

sListenSocket
[in] A descriptor identifying a socket that has already been called with the listen function. A server application waits for attempts to connect on this socket.
sAcceptSocket
[in] A descriptor identifying a socket on which to accept an incoming connection. This socket must not be bound or connected.
lpOutputBuffer
[in] A pointer to a buffer that receives the first block of data sent on a new connection, the local address of the server, and the remote address of the client. The receive data is written to the first part of the buffer starting at offset zero, while the addresses are written to the latter part of the buffer. This parameter must be specified.
dwReceiveDataLength
[in] The number of bytes in the buffer that will be used for receiving data. If this parameter is specified as zero, then no receive operation is performed in conjunction with accepting the connection. Instead, the AcceptEx function completes as soon as a connection arrives without waiting for any data.
dwLocalAddressLength
[in] The number of bytes reserved for the local address information. This must be at least 16 bytes more than the maximum address length for the transport protocol in use.
dwRemoteAddressLength
[in] The number of bytes reserved for the remote address information. This must be at least 16 bytes more than the maximum address length for the transport protocol in use.
lpdwBytesReceived
[out] A pointer to a DWORD that receives the count of bytes received. This is set only if the operation completes synchronously. If it returns ERROR_IO_PENDING and is completed later, then this DWORD is never set and you must obtain the number of bytes read from the completion notification mechanism.
lpOverlapped
[in] An OVERLAPPED structure that is used to process the request. This parameter must be specified; it cannot be NULL.

Return Values

If no error occurs, the AcceptEx function completed successfully and a value of TRUE is returned.

If the function fails, AcceptEx returns FALSE. The WSAGetLastError function can then be called to return extended error information. If WSAGetLastError returns ERROR_IO_PENDING, then the operation was successfully initiated and is still in progress.

Remarks

The AcceptEx function combines several socket functions into a single API/kernel transition. The AcceptEx function, when successful, performs three tasks: a new connection is accepted, both the local and remote addresses for the connection are returned, and the first block of data sent by the remote is received. A program will make a connection to a socket more quickly using AcceptExinstead of the accept function.

A single output buffer receives the data, the local socket address (the server), and the remote socket address (the client). Using a single buffer improves performance, but the GetAcceptExSockaddrs function must be called to parse the buffer into its three distinct parts.

The buffer size for the local and remote address must be 16 bytes more than the size of the SOCKADDR structure for the transport protocol in use because the addresses are written in an internal format. For example, the size of a SOCKADDR_IN (the address structure for TCP/IP) is 16 bytes. Therefore, a buffer size of at least 32 bytes must be specified for the local and remote addresses.

The AcceptEx function uses overlapped I/O, unlike the Windows Sockets 1.1 accept function. If your application uses AcceptEx, it can service a large number of clients with a relatively small number of threads. As with all overlapped Win32 functions, either Win32 events or completion ports can be used as a completion notification mechanism.

Another key difference between the AcceptEx function and the Windows Sockets 1.1 accept function is that the AcceptEx function requires the caller to already have two sockets: one that specifies the socket on which to listen and one that specifies the socket on which to accept the connection. The sAcceptSocket parameter must be an open socket that is neither bound nor connected.

The lpNumberOfBytesTransferred parameter of the GetQueuedCompletionStatus function or the GetOverlappedResult function indicates the number of bytes received in the request.

When this operation is successfully completed, sAcceptHandle can be passed only to the following functions:

ReadFile
WriteFile
send
recv
TransmitFile
closesocket

Note If you have called the TransmitFile function with both the TF_DISCONNECT and TF_REUSE_SOCKET flags, the specified socket has been returned to a state in which it is neither bound nor connected. You can then pass the handle of the socket to the AcceptEx function in the sAcceptSocket parameter.

When the AcceptEx function returns, the socket sAcceptSocket is in the default state for a connected socket. The socket sAcceptSocket does not inherit the properties of the socket associated with sListenSocket parameter until SO_UPDATE_ACCEPT_CONTEXT is set on the socket. Use the setsockopt function to set the SO_UPDATE_ACCEPT_CONTEXT option, specifying sAcceptSocket as the socket handle and sListenSocket as the option value.

For example:

err = setsockopt( sAcceptSocket,
    SOL_SOCKET,
    SO_UPDATE_ACCEPT_CONTEXT,
    (char *)&sListenSocket,
    sizeof(sListenSocket) );

Use the getsockopt function with the SO_CONNECT_TIME option to check whether a connection has been accepted. If it has been accepted, you can determine how long the connection has been established. The return value is the number of seconds that the socket has been connected. If the socket is not connected, the getsockopt returns 0xFFFFFFFF. Checking a connection like this is necessary in order to check for connections that have been established for a while, but no data has been received. It is recommended that you terminate those connections.

For example:

INT seconds;
INT bytes = sizeof(seconds);
err = getsockopt( sAcceptSocket, SOL_SOCKET, SO_CONNECT_TIME,
                      (char *)&seconds, (PINT)&bytes );
if ( err != NO_ERROR ) {
    printf( "getsockopt(SO_CONNECT_TIME) failed: %ld\n", WSAGetLastError( ) );
    exit(1);
}

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in mswsock.h.
Import Library: Link with mswsock.lib.


bind

The Windows Sockets bind function associates a local address with a socket.

int bind (
  SOCKET s,
  const struct sockaddr FAR*  name,
  int namelen
);

Parameters

s
[in] A descriptor identifying an unbound socket.
name
[in] The address to assign to the socket from the SOCKADDR structure.
namelen
[in] The length of the name.

Remarks

The bind function is used on an unconnected socket before subsequent calls to the connect or listen functions. It is used to bind to either connection-oriented (stream) or connectionless (datagram) sockets. When a socket is created with a call to the socket function, it exists in a name space (address family), but it has no name assigned to it. Use bind to establish the local association of the socket by assigning a local name to an unnamed socket.

A name consists of three parts when using the Internet address family: the address family, a host address, and a port number that identifies the application. In Windows Sockets 2, the name parameter is not strictly interpreted as a pointer to a SOCKADDR structure. It is cast this way for Windows Sockets 1.1 compatibility. Service Providers are free to regard it as a pointer to a block of memory of size namelen. The first two bytes in this block (corresponding to the sa_family member of the SOCKADDR structure) must contain the address family that was used to create the socket. Otherwise, an error WSAEFAULT will occur.

If an application does not care what local address is assigned, specify the manifest constant value ADDR_ANY for the sa_data member of the name parameter. This allows the underlying service provider to use any appropriate network address, potentially simplifying application programming in the presence of multihomed hosts (that is, hosts that have more than one network interface and address).

For TCP/IP, if the port is specified as zero, the service provider will assign a unique port to the application with a value between 1024 and 5000. The application can use getsockname after bind to learn the address and the port that has been assigned to it. If the Internet address is equal to INADDR_ANY, getsockname will not necessarily be able to supply the address until the socket is connected, since several addresses can be valid if the host is multihomed. Binding to a specific port number other than port 0 is discouraged for client applications, since there is a danger of conflicting with another socket already using that port number.

Windows CE: For IrSocket implementation of this function:

  • The Af_irda.h must be explicitly included.
  • The SOCKADDR_IRDA_wcesdk_SOCKADDR_IRDA structure is used in the addr parameter.
  • The WSAENETDOWN error value is not supported.
  • There is no wildcard address equivalent to INADDR_ANY.

    IrSockets clients must call bind before using a connect function. If the service name is of the form "LSAP-SELxxx" where xxx is a decimal integer in the range 0-255, the address indicates a specific LSAP-SEL xxx rather than a service name. LSAP-SELxxx service names will cause no IAS calls. The socket will be bound directly to the LSAP-SEL specified bypassing IAS.

Return Values

If no error occurs, bind returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | A process on the machine is already bound to the same fully-qualified address and the socket has not been marked to allow address re-use with SO_REUSEADDR. For example, IP address and port are bound in the af_inet case) . (See the SO_REUSEADDR socket option under setsockopt.)
WSAEADDRNOTAVAIL | The specified address is not a valid address for this machine
WSAEFAULT | The name or the namelen parameter is not a valid part of the user address space, the namelen parameter is too small, the name parameter contains incorrect address format for the associated address family, or the first two bytes of the memory block specified by name does not match the address family associated with the socket descriptor s.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | The socket is already bound to an address.
WSAENOBUFS | Not enough buffers available, too many connections.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

connect, getsockname, listen, setsockopt, socket, WSACancelBlockingCall


closesocket

The Windows Sockets closesocket function closes an existing socket.

int closesocket (
  SOCKET s
);

Parameters

s
[in] A descriptor identifying a socket to close.

Remarks

The closesocket function closes a socket. Use it to release the socket descriptor s so further references to s will fail with the error WSAENOTSOCK. If this is the last reference to an underlying socket, the associated naming information and queued data are discarded. Any pending blocking, asynchronous calls issued by any thread in this process are canceled without posting any notification messages.

Any pending overlapped send and receive operations (WSASend/WSASendTo/WSARecv/WSARecvFrom with an overlapped socket) issued by any thread in this process are also canceled. Any event, completion routine, or completion port action specified for these overlapped operations is performed. The pending overlapped operations fail with the error status WSA_OPERATION_ABORTED.

An application should always have a matching call to closesocket for each successful call to socket to return any socket resources to the system.

The semantics of closesocket are affected by the socket options SO_LINGER and SO_DONTLINGER as follows (SO_DONTLINGER is enabled by default; SO_LINGER is disabled):

Option | Interval | Type of close | Wait for close?
SO_DONTLINGER | Do not care | Graceful | No
SO_LINGER | Zero | Hard | No
SO_LINGER | Nonzero | Graceful | Yes

If SO_LINGER is set with a zero time-out interval (that is, the LINGER structure members l_onoff is not zero and l_linger is zero), closesocket is not blocked even if queued data has not yet been sent or acknowledged. This is called a "hard" or "abortive" close, because the socket's virtual circuit is reset immediately, and any unsent data is lost. Any recv call on the remote side of the circuit will fail with WSAECONNRESET.

If SO_LINGER is set with a nonzero time-out interval on a blocking socket, the closesocket call blocks on a blocking socket until the remaining data has been sent or until the time-out expires. This is called a graceful disconnect. If the time-out expires before all data has been sent, the Windows Sockets implementation terminates the connection before closesocket returns.

Enabling SO_LINGER with a nonzero time-out interval on a nonblocking socket is not recommended. In this case, the call to closesocket will fail with an error of WSAEWOULDBLOCK if the close operation cannot be completed immediately. If closesocket fails with WSAEWOULDBLOCK the socket handle is still valid, and a disconnect is not initiated. The application must call closesocket again to close the socket.If SO_DONTLINGER is set on a stream socket by setting the l_onoff member of the LINGER structure to zero, the closesocket call will return immediately and does not receive WSAWOULDBLOCK whether the socket is blocking or nonblocking. However, any data queued for transmission will be sent, if possible, before the underlying socket is closed. This is also called a graceful disconnect. In this case, the Windows Sockets provider cannot release the socket and other resources for an arbitrary period, thus affecting applications that expect to use all available sockets. This is the default behavior (SO_DONTLINGER is set by default).

Note To assure that all data is sent and received on a connection, an application should call shutdown before calling closesocket (see Graceful shutdown, linger options and socket closure for more information). Also note, an FD_CLOSE network event will not be posted after closesocket is called.

Here is a summary of closesocket behavior:

  • if SO_DONTLINGER enabled (the default setting) it always returns immediately – connection is gracefully closed "in the background"
  • if SO_LINGER enabled with a zero time-out: it always returns immediately - connection is reset/terminated
  • if SO_LINGER enabled with nonzero time-out:

    – with blocking socket it blocks until all data sent or time-out expires

    – with nonblocking socket it returns immediately indicating failure

For additional information please see Graceful shutdown, linger options and socket closure for more information.

Windows CE: Windows CE does not support the WSAEINTR error value.

For IrSocket implementation:

  • The Af_irda.h file must be explicitly included.
  • The WSAENETDOWN error value is not supported.
  • The standard linger options are supported.

    Although IrDA does not provide a graceful close, IrSockets will defer closing until receive queues are purged. Thus, an application can send data and immediately call the socket function confident that the receiver will copy the data before receiving an FD_CLOSE message.

.

Return Values

If no error occurs, closesocket returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINTR | The (blocking) Windows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEWOULDBLOCK | The socket is marked as nonblocking and SO_LINGER is set to a nonzero time-out value.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, ioctlsocket, setsockopt, socket, WSAAsyncSelect, WSADuplicateSocket


connect

The Windows Sockets connect function establishes a connection to a specifed socket.

int connect (
  SOCKET s,
  const struct sockaddr FAR*  name,
  int namelen
);

Parameters

s
[in] A descriptor identifying an unconnected socket.
name
[in] The name of the socket to connect to.
namelen
[in] The length of the name parameter.

Remarks

The connect function is used to create a connection to the specified destination. If the socket, s, is unbound, unique values are assigned to the local association by the system, and the socket is marked as bound.

For connection-oriented sockets (for example, type SOCK_STREAM), an active connection is initiated to the foreign host using name (an address in the name space of the socket; for a detailed description, please see bind and SOCKADDR). When the socket call completes successfully, the socket is ready to send/receive data. If the address member of the structure specified by the name parameter is all zeroes, connect will return the error WSAEADDRNOTAVAIL. Any attempt to re-connect an active connection will fail with the error code WSAEISCONN.

For connection-oriented, nonblocking sockets, it is often not possible to complete the connection immediately. In such a case, this function returns the error WSAEWOULDBLOCK. However, the operation proceeds. When the success or failure outcome becomes known, it may be reported in one of several ways depending on how the client registers for notification. If the client uses the select function, success is reported in the writefds set and failure is reported in the exceptfds set. If the client uses the functions WSAAsyncSelect or WSAEventSelect, the notification is announced with FD_CONNECT and the error code associated with the FD_CONNECT indicates either success or a specific reason for failure

For a connectionless socket (for example, type SOCK_DGRAM), the operation performed by connect is merely to establish a default destination address that will be used on subsequent send/WSASend and recv/WSARecv calls. Any datagrams received from an address other than the destination address specified will be discarded. If the address member of the structure specifed by name is all zeroes, the socket will be "dis-connected." Then, the default remote address will be indeterminate, so send/WSASend and recv/WSARecv calls will return the error code WSAENOTCONN. However, sendto /WSASendTo and recvfrom /WSARecvFrom can still be used. The default destination can be changed by simply calling connect again, even if the socket is already connected. Any datagrams queued for receipt are discarded if name is different from the previous connect.

For connectionless sockets, name can indicate any valid address, including a broadcast address. However, to connect to a broadcast address, a socket must use setsockopt to enable the SO_BROADCAST option. Otherwise, connect will fail with the error code WSAEACCES.

When a connection between sockets is broken, the sockets should be discarded and recreated. When a problem develops on a connected socket, the application must discard and recreate the needed sockets in order to return to a stable point.

Windows CE: Windows CE does not support the WSAEINTR error value.

For IrSocket implementation:

  • The Af_irda.h file must be explicitly included.
  • If WSAENETDOWN is returned, an existing IrDA connection was detected at the media access level.
  • If WSAEADDRINUSE is returned, active connections to a device with a different address exist.
  • If WSAEINPROGRESS is returned, IAS name resolution failed because another IAS query is in progress. Retry the operation at one second intervals.
  • If WSAEISCONN is returned, the socket is already connected or an exclusive/multiplexed mode change failed.

IrSockets implements the connect function with addresses of the form sockaddr_irda. Typically, a client application will create a socket with the socket function, scan the immediate vicinity for IrDA devices with the IRLMP_ENUMDEVICES socket option, choose a device from the returned list, form an address, and call connect. There is no difference in blocking and non-blocking semantics.

Return Values

If no error occurs, connect returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.

On a blocking socket, the return value indicates success or failure of the connection attempt.

With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK. In this case, there are three different steps you can take:

  1. Use the select function to determine the completion of the connection request by checking to see if the socket is writeable.
  2. If the application is using WSAAsyncSelect to indicate interest in connection events, then the application will receive an FD_CONNECT notification indicating that the connect operation is complete (successfully or not).
  3. If the application is using WSAEventSelect to indicate interest in connection events, then the associated event object will be signaled indicating that the connect operation is complete (successfully or not).

Until the connection attempt completes on a nonblocking socket, all subsequent calls to connect on the same socket will fail with the error code WSAEALREADY, and WSAEISCONN when the connection completes successfully. Due to ambiguities in version 1.1 of the Windows Sockets specification, error codes returned from connect while a connection is already pending may vary among implementations. As a result, it is not recommended that applications use multiple calls to connect to detect connection completion. If they do, they must be prepared to handle WSAEINVAL and WSAEWOULDBLOCK error values the same way that they handle WSAEALREADY, to assure robust execution.

If the error code returned indicates the connection attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the application can call connect again for the same socket.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs when executing bind, but could be delayed until this function if the bind was to a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function.
WSAEINTR | The (blocking) Windows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEALREADY | A nonblocking connect call is in progress on the specified socket. Note In order to preserve backward compatibility, this error is reported as WSAEINVAL to Windows Sockets 1.1 applications that link to either WINSOCK.DLL or WSOCK32.DLL.
WSAEADDRNOTAVAIL | The remote address is not a valid address (such as ADDR_ANY).
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to connect was forcefully rejected.
WSAEFAULT | The name or the namelen parameter is not a valid part of the user address space, the namelen parameter is too small, or the name parameter contains incorrect address format for the associated address family.
WSAEINVAL | The parameter s is a listening socket, or the destination address specified is not consistent with that of the constrained group the socket belongs to.
WSAEISCONN | The socket is already connected (connection-oriented sockets only).
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAENOBUFS | No buffer space is available. The socket cannot be connected.
WSAENOTSOCK | The descriptor is not a socket.
WSAETIMEDOUT | Attempt to connect timed out without establishing a connection.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the connection cannot be completed immediately.
WSAEACCES | Attempt to connect datagram socket to broadcast address failed because setsockopt option SO_BROADCAST is not enabled.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, bind, getsockname, select, socket, WSAAsyncSelect, WSAConnect


EnumProtocols

Important The EnumProtocols function is a Microsoft-specific extension to the Windows Sockets 1.1 specification. This function is obsolete. For the convenience of Windows Sockets 1.1 developers, the reference material is below.

The WSAEnumProtocols function provides equivalent functionality in Windows Sockets 2.

The EnumProtocols function obtains information about a specified set of network protocols that are active on a local host.

INT EnumProtocols(
  LPINT lpiProtocols,       // pointer to array of protocol
                            // identifiers
  LPVOID lpProtocolBuffer,  // pointer to buffer to receive protocol
                            // information
  LPDWORD lpdwBufferLength  // pointer to variable that specifies
                            // the size of the receiving buffer
);

Parameters

lpiProtocols
Pointer to a null-terminated array of protocol identifiers. The EnumProtocols function obtains information about the protocols specified by this array.

If lpiProtocols is NULL, the function obtains information about all available protocols.

The following protocol identifier values are defined:
Value | Protocol
IPPROTO_TCP | TCP/IP, a connection/stream oriented protocol
IPPROTO_UDP | User Datagram Protocol (UDP/IP), a connectionless datagram protocol
ISOPROTO_TP4 | ISO connection-oriented transport protocol
NSPROTO_IPX | IPX
NSPROTO_SPX | SPX
NSPROTO_SPXII | SPX II

lpProtocolBuffer
Pointer to a buffer that the function fills with an array of PROTOCOL_INFO data structures.
lpdwBufferLength
Pointer to a variable that, on input, specifies the size, in bytes, of the buffer pointed to by lpProtocolBuffer.

On output, the function sets this variable to the minimum buffer size needed to retrieve all of the requested information. For the function to succeed, the buffer must be at least this size.

Return Values

If the function succeeds, the return value is the number of PROTOCOL_INFO data structures written to the buffer pointed to by lpProtocolBuffer.

If the function fails, the return value is SOCKET_ERROR ( – 1). To get extended error information, call GetLastError. GetLastError can return the following extended error code:

Value | Meaning
ERROR_INSUFFICIENT_BUFFER | The buffer pointed to by lpProtocolBuffer was too small to receive all of the relevant PROTOCOL_INFO structures. Call the function with a buffer at least as large as the value returned in *lpdwBufferLength.

Remarks

In the following sample code, the EnumProtocols function obtains information about all protocols that are available on a system. The code then examines each of the protocols in greater detail.

SOCKET
OpenConnection (
    PTSTR ServiceName,
    PGUID ServiceType,
    BOOL Reliable,
    BOOL MessageOriented,
    BOOL StreamOriented,
    BOOL Connectionless,
    PINT ProtocolUsed
    )
{
    // local variables
    INT protocols[MAX_PROTOCOLS+1];
    BYTE buffer[2048];
    DWORD bytesRequired;
    INT err;
    PPROTOCOL_INFO protocolInfo;
    PCSADDR_INFO csaddrInfo;
    INT protocolCount;
    INT addressCount;
    INT i;
    DWORD protocolIndex;
    SOCKET s;

    // First look up the protocols installed on this machine.
    //
    bytesRequired = sizeof(buffer);
    err = EnumProtocols( NULL, buffer, &bytesRequired );
    if ( err <= 0 )
        return INVALID_SOCKET;

    // Walk through the available protocols and pick out the ones which
    // support the desired characteristics.
    //
    protocolCount = err;
    protocolInfo = (PPROTOCOL_INFO)buffer;

    for ( i = 0, protocolIndex = 0;
        i < protocolCount && protocolIndex < MAX_PROTOCOLS;
        i++, protocolInfo++ ) {

        // If connection-oriented support is requested, then check if
        // supported by this protocol.  We assume here that connection-
        // oriented support implies fully reliable service.
        //

        if ( Reliable ) {
            // Check to see if the protocol is reliable.  It must
            // guarantee both delivery of all data and the order in
            // which the data arrives.
            //
            if ( (protocolInfo->dwServiceFlags &
                    XP_GUARANTEED_DELIVERY) == 0
                ||
                    (protocolInfo->dwServiceFlags &
                    XP_GUARANTEED_ORDER) == 0 ) {

                continue;
                }

            // Check to see that the protocol matches the stream/message
            // characteristics requested.
            //
            if ( StreamOriented &&
                (protocolInfo->dwServiceFlags & XP_MESSAGE_ORIENTED)
                    != 0 &&
                (protocolInfo->dwServiceFlags & XP_PSEUDO_STREAM)
                     == 0 ) {
                continue;
                }

            if ( MessageOriented &&
                    (protocolInfo->dwServiceFlags & XP_MESSAGE_ORIENTED)
                              == 0 ) {
                continue;
                }

            }
        else if ( Connectionless ) {
            // Make sure that this is a connectionless protocol.
            //
            if ( (protocolInfo->dwServiceFlags & XP_CONNECTIONLESS)
                     != 0 )
                continue;
            }

        // This protocol fits all the criteria.  Add it to the list of
        // protocols in which we're interested.
        //
        protocols[protocolIndex++] = protocolInfo->iProtocol;
        }

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.
Import Library: Link with wsock32.lib.

See Also

GetAddressByName, PROTOCOL_INFO


GetAcceptExSockaddrs

Notice This function is a Microsoft-specific extension to the Windows Sockets specification. For more information, see Microsoft Extensions and Windows Sockets 2.

The Windows Sockets GetAcceptExSockaddrs function parses the data obtained from a call to the AcceptEx function and passes the local and remote addresses to a SOCKADDR structure.

VOID GetAcceptExSockaddrs (
  PVOID lpOutputBuffer,
  DWORD dwReceiveDataLength,
  DWORD dwLocalAddressLength,
  DWORD dwRemoteAddressLength,
  LPSOCKADDR *LocalSockaddr,
  LPINT LocalSockaddrLength,
  LPSOCKADDR *RemoteSockaddr,
  LPINT RemoteSockaddrLength
);

Parameters

lpOutputBuffer
[in] A pointer to a buffer that receives the first block of data sent on a connection resulting from an AcceptEx call. It must be the same lpOutputBuffer parameter that was passed to the AcceptEx function.
dwReceiveDataLength
[in] The number of bytes in the buffer that will be used for receiving the first data. This must be equal to the dwReceiveDataLength parameter that was passed to the AcceptEx function.
dwLocalAddressLength
[in] The number of bytes reserved for the local address information. This must be equal to the dwLocalAddressLength parameter that was passed to the AcceptEx function.
dwRemoteAddressLength
[in] The number of bytes reserved for the remote address information. This must be equal to the dwRemoteAddressLength parameter that was passed to the AcceptEx function.
LocalSockaddr
[out] A pointer to the SOCKADDR structure that receives the local address of the connection (the same information that would be returned by the Windows Sockets getsockname function). This parameter must be specified.
LocalSockaddrLength
[out] The size of the local address. This parameter must be specified.
RemoteSockaddr
[out] A pointer to the SOCKADDR structure that receives the remote address of the connection (the same information that would be returned by the Windows Sockets getpeername function). This parameter must be specified.
RemoteSockaddrLength
[out] The size of the local address. This parameter must be specified.

Remarks

The GetAcceptExSockaddrs function is used exclusively with the AcceptEx function to parse the first data that the socket receives into local and remote addresses. You are required to use this function because the AcceptEx function writes address information in an internal (TDI) format. The GetAcceptExSockaddrs routine is required to locate the SOCKADDR structures in the buffer.

Return Values

This function does not return a value.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in mswsock.h.
Import Library: Link with mswsock.lib.


GetAddressByName

Important The GetAddressByName function is a Microsoft-specific extension to the Windows Sockets 1.1 specification. This function is obsolete. For the convenience of Windows Sockets 1.1 developers, the reference material is below.

The functions detailed in Protocol-Independent Name Resolution provide equivalent functionality in Windows Sockets 2.

The GetAddressByName function queries a name space, or a set of default name spaces, in order to obtain network address information for a specified network service. This process is known as service name resolution. A network service can also use the function to obtain local address information that it can use with the bind function.

INT GetAddressByName(
  DWORD dwNameSpace,     // name space to query for service address
                         // information
  LPGUID lpServiceType,  // the type of the service
  LPTSTR lpServiceName,  // the name of the service
  LPINT lpiProtocols,    // points to array of protocol identifiers
  DWORD dwResolution,    // set of bit flags that specify aspects of
                         // name resolution
  LPSERVICE_ASYNC_INFO lpServiceAsyncInfo,
                         // reserved for future use, must be NULL
  LPVOID lpCsaddrBuffer, // points to buffer to receive address
                         // information
  LPDWORD lpdwBufferLength,  // points to variable with address
                             // buffer size information
  LPTSTR lpAliasBuffer,  // points to buffer to receive alias
                         // information
  LPDWORD lpdwAliasBufferLength
                         // points to variable with alias buffer
                         // size information
);

Parameters

dwNameSpace
Specifies the name space, or a set of default name spaces, that the operating system will query for network address information.

Use one of the following constants to specify a name space:
Value | Name Space
NS_DEFAULT | A set of default name spaces. The function queries each name space within this set. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set. This is the value that most applications should use for dwNameSpace.
NS_DNS | The Domain Name System used in the Internet for host name resolution.
NS_NETBT | The NetBIOS over TCP/IP layer. All Windows NT systems register their computer names with NetBIOS. This name space is used to convert a computer name to an IP address that uses this registration. Note that NS_NETBT can access a WINS server to perform the resolution.
NS_SAP | The Netware Service Advertising Protocol. This can access the Netware bindery if appropriate. NS_SAP is a dynamic name space that allows registration of services.
NS_TCPIP_HOSTS | Lookup value in the <systemroot>\system32\drivers\etc\hosts file.
NS_TCPIP_LOCAL | Local TCP/IP name resolution mechanisms, including comparisons against the local host name and looks up host names and IP addresses in cache of host to IP address mappings.

Most calls to GetAddressByName should use the special value NS_DEFAULT. This lets a client get by with no knowledge of which name spaces are available on an internetwork. The system administrator determines name space access. Name spaces can come and go without the client having to be aware of the changes.

lpServiceType
Points to a globally unique identifier (GUID) that specifies the type of the network service. The header file SVCGUID.H includes definitions of several GUID service types, and macros for working with them.
lpServiceName
Points to a zero-terminated string that uniquely represents the service name. For example, "MY SNA SERVER".

Setting lpServiceName to NULL is the equivalent of setting dwResolution to RES_SERVICE. The function operates in its second mode, obtaining the local address to which a service of the specified type should bind. The function stores the local address within the LocalAddr member of the CSADDR_INFO structures stored into *lpCsaddrBuffer.

If dwResolution is set to RES_SERVICE, the function ignores the lpServiceName parameter.

If dwNameSpace is set to NS_DNS, *lpServiceName is the name of the host.

lpiProtocols
Points to a zero-terminated array of protocol identifiers. The function restricts a name resolution attempt to name space providers that offer these protocols. This lets the caller limit the scope of the search.

If lpiProtocols is NULL, the function obtains information on all available protocols.

dwResolution
A set of bit flags that specify aspects of the service name resolution process. The following bit flags are defined:
Value | Meaning
RES_SERVICE If this flag is set, the function obtains the address to which a service of the specified type should bind. This is the equivalent of setting lpServiceName to NULL.

If this flag is clear, normal name resolution occurs.

RES_FIND_MULTIPLE | If this flag is set, the operating system performs an extensive search of all name spaces for the service. It will ask every appropriate name space to resolve the service name. If this flag is clear, the operating system stops looking for service addresses as soon as one is found.
RES_SOFT_SEARCH This flag is valid if the name space supports multiple levels of searching.

If this flag is valid and set, the operating system performs a simple and quick search of the name space. This is useful if an application only needs to obtain easy-to-find addresses for the service.

If this flag is valid and clear, the operating system performs a more extensive search of the name space.

lplpServiceAsyncInfo
Reserved for future use; must be set to NULL.
lpCsaddrBuffer
Points to a buffer to receive one or more CSADDR_INFO data structures. The number of structures written to the buffer depends on the amount of information found in the resolution attempt. You should assume that multiple structures will be written, although in many cases there will only be one.
lpdwBufferLength
Points to a variable that, upon input, specifies the size, in bytes, of the buffer pointed to by lpCsaddrBuffer.

Upon output, this variable contains the total number of bytes required to store the array of CSADDR_INFO structures. If this value is less than or equal to the input value of *lpdwBufferLength, and the function is successful, this is the number of bytes actually stored in the buffer. If this value is greater than the input value of *lpdwBufferLength, the buffer was too small, and the output value of *lpdwBufferLength is the minimal required buffer size.

lpAliasBuffer
Points to a buffer to receive alias information for the network service.

If a name space supports aliases, the function stores an array of zero-terminated name strings into the buffer pointed to by lpAliasBuffer. There is a double zero-terminator at the end of the list. The first name in the array is the service's primary name. Names that follow are aliases. An example of a name space that supports aliases is DNS.

If a name space does not support aliases, it stores a double zero-terminator into the buffer.

This parameter is optional, and can be set to NULL.

lpdwAliasBufferLength
Points to a variable that, upon input, specifies the size, in bytes, of the buffer pointed to by lpAliasBuffer.

Upon output, this variable contains the total number of bytes required to store the array of name strings. If this value is less than or equal to the input value of *lpdwAliasBufferLength, and the function is successful, this is the number of bytes actually stored in the buffer. If this value is greater than the input value of *lpdwAliasBufferLength, the buffer was too small, and the output value of *lpdwAliasBufferLength is the minimal required buffer size.

If lpAliasBuffer is NULL, lpdwAliasBufferLength is meaningless and can also be NULL.

Return Values

If the function succeeds, the return value is the number of CSADDR_INFO data structures written to the buffer pointed to by lpCsaddrBuffer.

If the function fails, the return value is SOCKET_ERROR( – 1). To get extended error information, call GetLastError. GetLastError can return the following extended error value:

Value | Meaning
ERROR_INSUFFICIENT_BUFFER | The buffer pointed to by lpCsaddrBuffer was too small to receive all of the relevant CSADDR_INFO structures. Call the function with a buffer at least as large as the value returned in *lpdwBufferLength.

Remarks

This function is a more powerful version of the Windows Sockets function gethostbyname The GetAddressByName function works with multiple name services.

The GetAddressByName function lets a client obtain a Windows Sockets address for a network service. The client specifies the service of interest by its service type and service name.

Many name services support a default prefix or suffix that the name service provider considers when resolving service names. For example, in the DNS name space, if a domain is named "nt.microsoft.com", and "ftp millikan" is provided as input, the DNS software fails to resolve "millikan", but successfully resolves "millikan.nt.microsoft.com".

Note that the GetAddressByName function can search for a service address in two ways: within a particular name space, or within a set of default name spaces. Using a default name space, an administrator can specify that certain name spaces will be searched for service addresses only if specified by name. An administrator or name space setup program can also control the ordering of name space searches.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.
Import Library: Link with wsock32.lib.

See Also

gethostbyname, CSADDR_INFO


gethostbyaddr

The Windows Sockets gethostbyaddr function retrieves the host information corresponding to a network address.

struct HOSTENT FAR * gethostbyaddr (
  const char FAR * addr,
  int len,
  int type
);

Parameters

addr
[in] A pointer to an address in network byte order.
len
[in] The length of the address.
type
[in] The type of the address.

Remarks

The gethostbyaddr function returns a pointer to the HOSTENT structure that contains the name and address corresponding to the given network address. All strings are null-terminated.

Return Values

If no error occurs, gethostbyaddr returns a pointer to the HOSTENT structure. Otherwise, it returns a NULL pointer, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAHOST_NOT_FOUND | Authoritative Answer Host not found.
WSATRY_AGAIN | Non-Authoritative Host not found, or server failed.
WSANO_RECOVERY | Nonrecoverable error occurred.
WSANO_DATA | Valid name, no data record of requested type.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEAFNOSUPPORT | The type specified is not supported by the Windows Sockets implementation.
WSAEFAULT | The addr parameter is not a valid part of the user address space, or the len parameter is too small.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

gethostbyname, HOSTENT, WSAAsyncGetHostByAddr


gethostbyname

The Windows Sockets gethostbyname function retrieves host information corresponding to a host name from a host database.

struct hostent FAR * gethostbyname (
  const char FAR * name
);

Parameters

name
[out] A pointer to the null-terminated name of the host to resolve.

Remarks

The gethostbyname function returns a pointer to a HOSTENT structure — a structure allocated by Windows Sockets. The HOSTENT structure contains the results of a successful search for the host specified in the name parameter.

The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, so the application should copy any information it needs before issuing any other Windows Sockets function calls.

The gethostbyname function cannot resolve IP address strings passed to it. Such a request is treated exactly as if an unknown host name were passed. Use inet_addr to convert an IP address string the string to an actual IP address, then use another function, gethostbyaddr, to obtain the contents of the HOSTENT structure.

The gethostbyname function resolves the string returned by a successful call to gethostname.

Return Values

If no error occurs, gethostbyname returns a pointer to the HOSTENT structure described above. Otherwise, it returns a NULL pointer and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAHOST_NOT_FOUND | Authoritative Answer Host not found.
WSATRY_AGAIN | Non-Authoritative Host not found, or server failure.
WSANO_RECOVERY | Nonrecoverable error occurred.
WSANO_DATA | Valid name, no data record of requested type.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The name parameter is not a valid part of the user address space.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

gethostbyaddr, WSAAsyncGetHostByName


gethostname

The Windows Sockets gethostname function returns the standard host name for the local machine.

int gethostname (
  char FAR * name,
  int namelen
);

Parameters

name
[out] A pointer to a buffer that receives the local host name.
namelen
[in] The length of the buffer.

Remarks

The gethostname function returns the name of the local host into the buffer specified by the name parameter. The host name is returned as a null-terminated string. The form of the host name is dependent on the Windows Sockets provider — it can be a simple host name, or it can be a fully qualified domain name. However, it is guaranteed that the name returned will be successfully parsed by gethostbyname and WSAAsyncGetHostByName.

Note If no local host name has been configured, gethostname must succeed and return a token host name that gethostbyname or WSAAsyncGetHostByName can resolve.

Return Values

If no error occurs, gethostname returns zero. Otherwise, it returns SOCKET_ERROR and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSAEFAULT | The name parameter is not a valid part of the user address space, or the buffer size specified by namelen parameter is too small to hold the complete host name.
WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

gethostbyname, WSAAsyncGetHostByName


GetNameByType

Important The GetNameByType function is a Microsoft-specific extension to the Windows Sockets 1.1 specification. This function is obsolete. For the convenience of Windows Sockets 1.1 developers, the reference material is below.

The functions detailed in Protocol-Independent Name Resolution provide equivalent functionality in Windows Sockets 2.

The GetNameByType function obtains the name of a network service. The network service is specified by its service type.

INT GetNameByType(
  LPGUID lpServiceType,  // points to network service type GUID
  LPTSTR lpServiceName,  // points to buffer to receive name of
                         // network service
  DWORD dwNameLength     // points to variable that specifies buffer
                         // size
);

Parameters

lpServiceType
Points to a globally unique identifier (GUID) that specifies the type of the network service. The header file SVCGUID.H includes definitions of several GUID service types, and macros for working with them.
lpServiceName
Points to a buffer to receive a zero-terminated string that uniquely represents the name of the network service.
dwNameLength
Points to a variable that, on input, specifies the size of the buffer pointed to by lpServiceName. On output, the variable contains the actual size of the service name string.

Return Values

If the function succeeds, the return value is not SOCKET_ERROR ( –1).

If the function fails, the return value is SOCKET_ERROR ( –1). To get extended error information, call GetLastError.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.
Import Library: Link with wsock32.lib.

See Also

GetTypeByName


getpeername

The Windows Sockets getpeername function retrieves the name of the peer to which a socket is connected.

int getpeername (
  SOCKET s,
  struct sockaddr FAR*  name,
  int FAR*  namelen
);

Parameters

s
[in] A descriptor identifying a connected socket.
name
[out] The structure that receives the name of the peer.
namelen
[in/out] A pointer to the size of the name structure.

Remarks

The getpeername function retrieves the name of the peer connected to the socket s and stores it in the aSOCKADDR structure identified by name. The getpeername function can be used only on a connected socket. For datagram sockets, only the name of a peer specified in a previous connect call will be returned—any name specified by a previous sendto call will not be returned by getpeername.

On call, the namelen argument contains the size of the name buffer, in bytes. On return, the namelen parameter contains the actual size in bytes of the name returned.

Return Values

If no error occurs, getpeername returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The name or the namelen parameter is not a valid part of the user address space, or the namelen parameter is too small.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTCONN | The socket is not connected.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with wsock32.lib.

See Also

bind, getsockname, socket


getprotobyname

The Windows Sockets getprotobyname function retrieves the protocol information corresponding to a protocol name.

struct PROTOENT FAR * getprotobyname (
  const char FAR * name
);

Parameters

name
[in] A pointer to a null-terminated protocol name.

Remarks

The getprotobyname function returns a pointer to the PROTOENT structure containing the name(s) and protocol number that correspond to the protocol specified in the name parameter. All strings are null-terminated. The PROTOENT structure is allocated by the Windows Sockets library. An application must never attempt to modify this structure or to free any of its components. Furthermore, like HOSTENT, only one copy of this structure is allocated per thread, so the application should copy any information that it needs before issuing any other Windows Sockets function calls.

Return Values

If no error occurs, getprotobyname returns a pointer to the PROTOENT. Otherwise, it returns a NULL pointer and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAHOST_NOT_FOUND | Authoritative Answer Protocol not found.
WSATRY_AGAIN | Non-Authoritative Protocol not found, or server failure.
WSANO_RECOVERY | Nonrecoverable errors, the protocols database is not accessible.
WSANO_DATA | Valid name, no data record of requested type.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The name parameter is not a valid part of the user address space.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getprotobynumber, WSAAsyncGetProtoByName


getprotobynumber

The Windows Sockets getprotobynumber function retrieves protocol information corresponding to a protocol number.

struct PROTOENT FAR * getprotobynumber (
  int number
);

Parameters

number
[in] A protocol number, in host byte order.

Remarks

This getprotobynumber function returns a pointer to the PROTOENT structure as previously described in getprotobyname. The contents of the structure correspond to the given protocol number.

The pointer that is returned points to the structure allocated by Windows Sockets. The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, so the application should copy any information that it needs before issuing any other Windows Sockets function calls.

Return Values

If no error occurs, getprotobynumber returns a pointer to the PROTOENT structure. Otherwise, it returns a NULL pointer and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAHOST_NOT_FOUND | Authoritative Answer Protocol not found.
WSATRY_AGAIN | Non-Authoritative Protocol not found, or server failure.
WSANO_RECOVERY | Nonrecoverable errors, the protocols database is not accessible.
WSANO_DATA | Valid name, no data record of requested type.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getprotobyname, WSAAsyncGetProtoByNumber


getservbyname

The Windows Sockets getservbyname function retrieves service information corresponding to a service name and protocol.

struct servent FAR * getservbyname (
  const char FAR * name,
  const char FAR * proto
);

Parameters

name
[in] A pointer to a null-terminated service name.
proto
[in] An optional pointer to a null-terminated protocol name. If this pointer is NULL, getservbyname returns the first service entry where name matches the s_name member of the SERVENT structure or the s_aliases member of the SERVENT structure. Otherwise, getservbyname matches both the name and the proto.

Remarks

The getservbyname function returns a pointer to the SERVENT structure containing the name(s) and service number that match the string in the name parameter. All strings are null-terminated.

The pointer that is returned points to the SERVENT structure allocated by the Windows Sockets library. The application must never attempt to modify this structure or to free any of its components. Furthermore only one copy of this structure is allocated per thread, so the application should copy any information it needs before issuing any other Windows Sockets function calls.

Return Values

If no error occurs, getservbyname returns a pointer to the SERVENT structure. Otherwise, it returns a NULL pointer and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAHOST_NOT_FOUND | Authoritative Answer Service not found.
WSATRY_AGAIN | Non-Authoritative Service not found, or server failure.
WSANO_RECOVERY | Nonrecoverable errors, the services database is not accessible.
WSANO_DATA | Valid name, no data record of requested type.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getservbyport, WSAAsyncGetServByName


getservbyport

The Windows Sockets getservbyport function retrieves service information corresponding to a port and protocol.

struct servent FAR * getservbyport (
  int port,
  const char FAR* proto
);

Parameters

port
[in] The port for a service, in network byte order.
proto
[in] An optional pointer to a protocol name. If this is NULL, getservbyport returns the first service entry for which the port matches the s_port of the SERVENT structure. Otherwise, getservbyport matches both the port and the proto parameters.

Remarks

The getservbyport function returns a pointer to a SERVENT structure as it does in the getservbyname function.

The SERVENT structure is allocated by Windows Sockets. The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, so the application should copy any information it needs before issuing any other Windows Sockets function calls.

Return Values

If no error occurs, getservbyport returns a pointer to the SERVENT structure. Otherwise, it returns a NULL pointer and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAHOST_NOT_FOUND | Authoritative Answer Service not found.
WSATRY_AGAIN | Non-Authoritative Service not found, or server failure.
WSANO_RECOVERY | Nonrecoverable errors, the services database is not accessible.
WSANO_DATA | Valid name, no data record of requested type.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The proto parameter is not a valid part of the user address space.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getservbyname, WSAAsyncGetServByPort


GetService

Important The GetService function is a Microsoft-specific extension to the Windows Sockets 1.1 specification. This function is obsolete. For the convenience of Windows Sockets 1.1 developers, the reference material is below..

The functions detailed in Protocol-Independent Name Resolution provide equivalent functionality in Windows Sockets 2.

The GetService function obtains information about a network service in the context of a set of default name spaces or a specified name space. The network service is specified by its type and name. The information about the service is obtained as a set of NS_SERVICE_INFO data structures.

INT GetService(
  DWORD dwNameSpace,   // specifies name space or spaces to search
  PGUID lpGuid,        // points to a GUID service type
  LPTSTR lpServiceName,
                       // points to a service name
  DWORD dwProperties,  // specifies service information to be
                       // obtained
  LPVOID lpBuffer,     // points to buffer to receive service
                       // information
  LPDWORD lpdwBufferSize,  // points to size of buffer, size of
                           // service information
  LPSERVICE_ASYNC_INFO lpServiceAsyncInfo
                       // reserved for future use, must be NULL
);

Parameters

dwNameSpace
Specifies the name space, or a set of default name spaces, that the operating system will query for information about the specified network service.

Use one of the following constants to specify a name space:
Value | Name Space
NS_DEFAULT | A set of default name spaces. The operating system will query each name space within this set. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set. NS_DEFAULT is the value that most applications should use for dwNameSpace.
NS_DNS | The Domain Name System used in the Internet for host name resolution.
NS_NETBT | The NetBIOS over TCP/IP layer. All Windows NT systems register their computer names with NetBIOS. This name space is used to resolve a computer name into an IP address using this registration. Note that NS_NETBT can access a WINS server to perform the resolution.
NS_SAP | The Netware Service Advertising Protocol. This can access the Netware bindery if appropriate. NS_SAP is a dynamic name space that allows registration of services.
NS_TCPIP_HOSTS | Looks up host names and IP addresses in the <systemroot>\system32\drivers\etc\hosts file.
NS_TCPIP_LOCAL | Local TCP/IP name resolution mechanisms, including comparisons against the local host name and looks up host names and IP addresses in cache of host to IP address mappings.

Most calls to GetService should use the special value NS_DEFAULT. This lets a client get by with no knowledge of which name spaces are available on an internetwork. The system administrator determines name space access. Name spaces can come and go without the client having to be aware of the changes.

lpGuid
Points to a globally unique identifier (GUID) that specifies the type of the network service. The header file SVCGUID.H includes GUID service types from many well-known services within the DNS and SAP name spaces.
lpServiceName
Points to a zero-terminated string that uniquely represents the service name. For example, "MY SNA SERVER".
dwProperties
A set of bit flags that specify the service information that the function obtains. Each of these bit flag constants, other than PROP_ALL, corresponds to a particular member of the SERVICE_INFO data structure. If the flag is set, the function puts information into the corresponding member of the data structures stored in *lpBuffer. The following bit flags are defined:
Value | Name Space
PROP_COMMENT | If this flag is set, the function stores data in the lpComment member of the data structures stored in *lpBuffer.
PROP_LOCALE | If this flag is set, the function stores data in the lpLocale member of the data structures stored in *lpBuffer.
PROP_DISPLAY_HINT | If this flag is set, the function stores data in the dwDisplayHint member of the data structures stored in *lpBuffer.
PROP_VERSION | If this flag is set, the function stores data in the dwVersion member of the data structures stored in *lpBuffer.
PROP_START_TIME | If this flag is set, the function stores data in the dwTime member of the data structures stored in *lpBuffer.
PROP_MACHINE | If this flag is set, the function stores data in the lpMachineName member of the data structures stored in *lpBuffer.
PROP_ADDRESSES | If this flag is set, the function stores data in the lpServiceAddress member of the data structures stored in *lpBuffer.
PROP_SD | If this flag is set, the function stores data in the ServiceSpecificInfo member of the data structures stored in *lpBuffer.
PROP_ALL | If this flag is set, the function stores data in all of the members of the data structures stored in *lpBuffer.

lpBuffer
Points to a buffer to receive an array of NS_SERVICE_INFO structures and associated service information. Each NS_SERVICE_INFO structure contains service information in the context of a particular name space. Note that if dwNameSpace is NS_DEFAULT, the function stores more than one structure into the buffer; otherwise, just one structure is stored.

Each NS_SERVICE_INFO structure contains a SERVICE_INFO structure. The members of these SERVICE_INFO structures will contain valid data based on the bit flags that are set in the dwProperties parameter. If a member's corresponding bit flag is not set in dwProperties, the member's value is undefined.

The function stores the NS_SERVICE_INFO structures in a consecutive array, starting at the beginning of the buffer. The pointers in the contained SERVICE_INFO structures point to information that is stored in the buffer between the end of the NS_SERVICE_INFO structures and the end of the buffer.

lpdwBufferSize
Points to a variable that, on input, contains the size, in bytes, of the buffer pointed to by lpBuffer. On output, this variable contains the number of bytes required to store the requested information. If this output value is greater than the input value, the function has failed due to insufficient buffer size.
lpServiceAsyncInfo
This parameter is reserved for future use. It must be set to NULL.

Return Values

If the function succeeds, the return value is the number of NS_SERVICE_INFO structures stored in *lpBuffer. Zero indicates that no structures were stored.

If the function fails, the return value is SOCKET_ERROR ( – 1). To get extended error information, call GetLastError. GetLastError can return one of the following extended error values:

Value | Meaning
ERROR_INSUFFICIENT_BUFFER | The buffer pointed to by lpBuffer is too small to receive all of the requested information. Call the function with a buffer at least as large as the value returned in *lpdwBufferSize.
ERROR_SERVICE_NOT_FOUND | The specified service was not found, or the specified name space is not in use. The function return value is zero in this case.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.
Import Library: Link with wsock32.lib.

See Also

SetService, NS_SERVICE_INFO, SERVICE_INFO


getsockname

The Windows Sockets getsockname function retrieves the local name for a socket.

int getsockname (
  SOCKET s,
  struct sockaddr FAR*  name,
  int FAR*  namelen
);

Parameters

s
[in] A descriptor identifying a bound socket.
name
[out] Receives the address (name) of the socket.
namelen
[in/out] The size of the name buffer.

Remarks

The getsockname function retrieves the current name for the specified socket descriptor in name. It is used on the bound or connected socket specified by the s parameter. The local association is returned. This call is especially useful when a connect call has been made without doing a bind first; the getsockname function provides the only way to determine the local association that has been set by the system.

On call, the namelen argument contains the size of the name buffer, in bytes. On return, the namelen parameter contains the actual size in bytes of the name parameter.

The getsockname function does not always return information about the host address when the socket has been bound to an unspecified address, unless the socket has been connected with connect or accept (for example, using ADDR_ANY). A Windows Sockets application must not assume that the address will be specified unless the socket is connected. The address that will be used for the socket is unknown unless the socket is connected when used in a multihomed host. If the socket is using a connectionless protocol, the address may not be available until I/O occurs on the socket.

Return Values

If no error occurs, getsockname returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The name or the namelen parameter is not a valid part of the user address space, or the namelen parameter is too small.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor is not a socket.
WSAEINVAL | The socket has not been bound to an address with bind, or ADDR_ANY is specified in bind but connection has not yet occurs.

QuickInfo

Windows NT: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with wsock32.lib.

See Also

bind, getpeername, socket


getsockopt

The Windows Sockets getsockopt function retrieves a socket option.

int getsockopt (
  SOCKET s,
  int level,
  int optname,
  char FAR* optval,
  int FAR*  optlen
);

Parameters

s
[in] A descriptor identifying a socket.
level
[in] The level at which the option is defined; the supported levels include SOL_SOCKET and IPPROTO_TCP. See the Windows Sockets 2 Protocol-Specific Annex (a separate document included with the Platform SDK) for more information on protocol-specific levels.
optname
[in] The socket option for which the value is to be retrieved.
optval
[out] A pointer to the buffer in which the value for the requested option is to be returned.
optlen
[in/out] A pointer to the size of the optval buffer.

Remarks

The getsockopt function retrieves the current value for a socket option associated with a socket of any type, in any state, and stores the result in optval. Options can exist at multiple protocol levels, but they are always present at the uppermost "socket'' level. Options affect socket operations, such as the packet routing and out-of-band data transfer.

The value associated with the selected option is returned in the buffer optval. The integer pointed to by optlen should originally contain the size of this buffer; on return, it will be set to the size of the value returned. For SO_LINGER, this will be the size of a LINGER structure. For most other options, it will be the size of an integer.

The application is responsible for allocating any memory space pointed to directly or indirectly by any of the parameters it specified.

If the option was never set with setsockopt, then getsockopt returns the default value for the option.

The following options are supported for getsockopt. The Type column identifies the type of data addressed by optval.

level = SOL_SOCKET

Value | Type | Meaning
SO_ACCEPTCONN | BOOL | Socket is listening.
SO_BROADCAST | BOOL | Socket is configured for the transmission of broadcast messages.
SO_DEBUG | BOOL | Debugging is enabled.
SO_DONTLINGER | BOOL | If true, the SO_LINGER option is disabled.
SO_DONTROUTE | BOOL | Routing is disabled.
SO_ERROR | int | Retrieve error status and clear.
SO_GROUP_ID | GROUP | The identifier of the group to which this socket belongs.
SO_GROUP_PRIORITY | int | The relative priority for sockets that are part of a socket group.
SO_KEEPALIVE | BOOL | Keepalives are being sent.
SO_LINGER | struct LINGER | Returns the current linger options.
SO_MAX_MSG_SIZE | unsigned int | Maximum size of a message for message-oriented socket types (for example, SOCK_DGRAM). Has no meaning for stream oriented sockets.
SO_OOBINLINE | BOOL | Out-of-band data is being received in the normal data stream. (See section Windows Sockets 1.1 Blocking Routines & EINPROGRESS for a discussion of this topic.)
SO_PROTOCOL_INFO | WSAPROTOCOL_INFO | Description of protocol info for protocol that is bound to this socket.
SO_RCVBUF | int | Buffer size for receives
SO_REUSEADDR | BOOL | The socket can be bound to an address which is already in use.
SO_SNDBUF | int | Buffer size for sends
SO_TYPE | int | The type of the socket (for example, SOCK_STREAM).
PVD_CONFIG | Service Provider Dependent | An "opaque" data structure object from the service provider associated with socket s. This object stores the current configuration information of the service provider. The exact format of this data structure is service provider specific.

level = IPPROTO_TCP

TCP_NODELAY BOOL Disables the Nagle algorithm for send coalescing.

BSD options not supported for getsockopt are:

Value | Type | Meaning
SO_RCVLOWAT | int | Receive low water mark
SO_RCVTIMEO | int | Receive time-out
SO_SNDLOWAT | int | Send low water mark
SO_SNDTIMEO | int | Send time-out
TCP_MAXSEG | int | Get TCP maximum segment size

Calling getsockopt with an unsupported option will result in an error code of WSAENOPROTOOPT being returned from WSAGetLastError.

SO_DEBUG
Windows Sockets service providers are encouraged (but not required) to supply output debug information if the SO_DEBUG option is set by an application. The mechanism for generating the debug information and the form it takes are beyond the scope of this document.
SO_ERROR
The SO_ERROR option returns and resets the per-socket based error code, which is different from the per-thread based error code that is handled using the WSAGetLastError and WSASetLastError function calls. A successful call using the socket does not reset the socket based error code returned by the SO_ERROR option.
SO_GROUP_ID
This option is reserved for future use with socket groups. This option is also exclusive to getsockopt. It indicates the identifier of the group to which this socket belongs. Socket group IDs are unique across all processes for a given service provider. If this socket is not a group socket, the value is NULL.
SO_GROUP_PRIORITY
This option is reserved for future use with socket groups. Group priority indicates the priority of the specified socket relative to other sockets within the socket group. Values are non-negative integers, with zero corresponding to the highest priority. Priority values represent a hint to the underlying service provider about how potentially scarce resources should be allocated. For example, whenever two or more sockets are both ready to transmit data, the highest priority socket (lowest value for SO_GROUP_PRIORITY) should be serviced first, with the remainder serviced in turn according to their relative priorities.

The WSAENOPROTOOPT error code is indicated for non group sockets or for service providers that do not support group sockets.

SO_KEEPALIVE
An application can request that a TCP/IP service provider enable the use of "keep-alive" packets on TCP connections by turning on the SO_KEEPALIVE socket option. A Windows Sockets provider need not support the use of keep-alive: if it does, the precise semantics are implementation-specific but should conform to section 4.2.3.6 of RFC 1122: Requirements for Internet Hosts — Communication Layers. If a connection is dropped as the result of "keep-alives" the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN.
SO_LINGER
SO_LINGER controls the action taken when unsent data is queued on a socket and a closesocket is performed. See closesocket for a description of the way in which the SO_LINGER settings affect the semantics of closesocket. The application gets the current behavior by retrieving a LINGER structure (pointed to by the optval parameter).
SO_MAX_MSG_SIZE
This is a get-only socket option that indicates the maximum outbound (send) size of a message for message-oriented socket types (for example, SOCK_DGRAM) as implemented by a particular service provider. It has no meaning for byte stream oriented sockets. There is no provision to find out the maximum inbound message size
SO_PROTOCOL_INFO
This is a get-only option that supplies the WSAPROTOCOL_INFO structure associated with this socket. See WSAEnumProtocols for more information about this structure.
SO_SNDBUF
When a Windows Sockets implementation supports the SO_RCVBUF and SO_SNDBUF options, an application can request different buffer sizes (larger or smaller). The call to setsockopt can succeed even if the implementation did not provide the whole amount requested. An application must call this function with the same option to check the buffer size actually provided.
SO_REUSEADDR
By default, a socket cannot be bound (see bind) to a local address that is already in use. On occasion, however, it can be necessary to "re-use" an address in this way. Because every connection is uniquely identified by the combination of local and remote addresses, there is no problem with having two sockets bound to the same local address as long as the remote addresses are different. To inform the Windows Sockets provider that a bind on a socket should not be disallowed because the desired address is already in use by another socket, the application should set the SO_REUSEADDR socket option for the socket before issuing the bind. Note that the option is interpreted only at the time of the bind: it is therefore unnecessary (but harmless) to set the option on a socket that is not to be bound to an existing address, and setting or resetting the option after the bind has no effect on this or any other socket.
PVD_CONFIG
This option retrieves an "opaque" data structure object from the service provider associated with socket s. This object stores the current configuration information of the service provider. The exact format of this data structure is service provider specific.
TCP_NODELAY
The TCP_NODELAY option is specific to TCP/IP service providers. The Nagle algorithm is disabled if the TCP_NODELAY option is enabled (and vice versa). The Nagle algorithm (described in RFC 896) is very effective in reducing the number of small packets sent by a host. The process involves buffering send data when there is unacknowledged data already "in flight" or buffering send data until a full-size packet can be sent. It is highly recommended that Windows Sockets implementations enable the Nagle Algorithm by default because,for the vast majority of application protocols, the Nagle Algorithm can deliver significant performance enhancements. However, for some applications this algorithm can impede performance, and setsockopt with the same option can be used to turn it off. These are applications where many small messages are sent, and the time delays between the messages are maintained.

Windows CE: For IrSockets implementation:

  • The Af_irda.h file must be explicitly included.
  • The WSAENETDOWN return value is not supported.

IrSockets supports several special socket options:

Value | Type | Meaning
IRLMP_ENUMDEVICES | * DEVICELIST | Describes devices in range.
IRLMP_IAS_QUERY | * IAS_QUERY | Retrieve IAS attributes.
IRLMP_SEND_PDU_LEN | * int | Retrieves max number of bytes that can be sent in any one send() call while in IRLMP_IRLPT_MODE (printing). This value should be retrieved after the connect() completes but before any data is sent.

The DEVICELIST structure is an extendible array of device descriptions. IrSockets fills in as many device descriptions as can fit in the supplied buffer and returns in the optlen result parameter the required size if the buffer is of insufficient size. The device description consists of a device identifier necessary to form a sockaddr_irda structure and a displayable string describing the device.

The IAS_QUERY structure is used to retrieve a single attribute of a single class. The application specifies the device and class to query and the attribute and attribute type. It is expected that the application allocates a buffer of the necessary size for the returned parameters.

Many SO level socket options are not meaningful to IrSockets. Only SO_LINGER and SO_DONTLINGER are specifically supported.

Return Values

If no error occurs, getsockopt returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | One of the optval or the optlen parameters is not a valid part of the user address space, or the optlen parameter is too small.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | The level parameter is unknown or invalid.
WSAENOPROTOOPT | The option is unknown or unsupported by the indicated protocol family.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

setsockopt, socket, WSAAsyncSelect, WSAConnect, WSAGetLastError, WSASetLastError


GetTypeByName

Important The GetTypeByName function is a Microsoft-specific extension to the Windows Sockets 1.1 specification. This function is obsolete. For the convenience of Windows Sockets 1.1 developers, the reference material is below.

The functions detailed in Protocol-Independent Name Resolution provide equivalent functionality in Windows Sockets 2.

The GetTypeByName function obtains a service type GUID for a network service specified by name.

INT GetTypeByName(
  LPTSTR lpServiceName, // points to the name of the network service
  PGUID lpServiceType   // points to a variable to receive network
                        // service type
);

Parameters

lpServiceName
Points to a zero-terminated string that uniquely represents the name of the service. For example, "MY SNA SERVER".
lpServiceType
Points to a variable to receive a globally unique identifier (GUID) that specifies the type of the network service. The header file SVCGUID.H includes definitions of several GUID service types and macros for working with them.

Return Values

If the function succeeds, the return value is zero.

If the function fails, the return value is SOCKET_ERROR( – 1). To get extended error information, call GetLastError. GetLastError can return the following extended error value:

Value | Meaning
ERROR_SERVICE_DOES_NOT_EXIST | The specified service type is unknown.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.
Import Library: Link with wsock32.lib.

See Also

GetNameByType


htonl

The Windows Sockets htonl function converts a u_long from host to TCP/IP network byte order (which is big-endian).

u_long htonl (
  u_long hostlong
);

Parameters

hostlong
[in] A 32-bit number in host byte order.

Remarks

The htonl function takes a 32-bit number in host byte order and returns a 32-bit number in the network byte order used in TCP/IP networks.

Return Values

The htonl function returns the value in TCP/IP's network byte order.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

htons, ntohl, ntohs, WSAHtonl, WSAHtons, WSANtohl, WSANtohs


htons

The Windows Sockets htons function converts a u_short from host to TCP/IP network byte order (which is big-endian).

u_short htons (
  u_short hostshort
);

Parameters

hostshort
[in] A 16-bit number in host byte order.

Remarks

The htons function takes a 16-bit number in host byte order and returns a 16-bit number in network byte order used in TCP/IP networks.

Return Values

The htons function returns the value in TCP/IP network byte order.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

htonl, ntohl, ntohs, WSAHtonl, WSAHtons, WSANtohl, WSANtohs


inet_addr

The Windows Sockets inet_addr function converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the IN_ADDR structure.

unsigned long inet_addr (
  const char FAR * cp
);

Parameters

cp
[in] A null-terminated character string representing a number expressed in the Internet standard ".'' (dotted) notation.

Remarks

The inet_addr function interprets the character string specified by the cp parameter. This string represents a numeric Internet address expressed in the Internet standard ".'' notation. The value returned is a number suitable for use as an Internet address. All Internet addresses are returned in IP's network order (bytes ordered from left to right).

Internet Addresses

Values specified using the ".'' notation take one of the following forms:

a.b.c.d a.b.c a.b a

When four parts are specified, each is interpreted as a byte of data and assigned, from left to right, to the four bytes of an Internet address. When an Internet address is viewed as a 32-bit integer quantity on the Intel architecture, the bytes referred to above appear as "d.c.b.a''. That is, the bytes on an Intel processor are ordered from right to left.

The parts that make up an address in "." notation can be decimal, octal or hexidecimal as specified in the C language. Numbers that start with "0x" or "0X" imply hexidecimal. Numbers that start with "0" imply octal. All other numbers are interpreted at decimal.

"4.3.2.16" | decimal
"004.003.002.020" | octal
"0x4.0x3.0x2.0x10" | hexidecimal
"4.003.002.0x10" | mix

Note The following notations are only used by Berkeley, and nowhere else on the Internet. In the interests of compatibility with their software, they are supported as specified.

When a three part address is specified, the last part is interpreted as a 16-bit quantity and placed in the right most two bytes of the network address. This makes the three part address format convenient for specifying Class B network addresses as "128.net.host''.

When a two part address is specified, the last part is interpreted as a 24-bit quantity and placed in the right most three bytes of the network address. This makes the two part address format convenient for specifying Class A network addresses as "net.host''.

When only one part is given, the value is stored directly in the network address without any byte rearrangement.

Return Values

If no error occurs, inet_addr returns an unsigned long value containing a suitable binary representation of the Internet address given. If the string in the cp parameter does not contain a legitimate Internet address, for example if a portion of an "a.b.c.d" address exceeds 255, inet_addr returns the value INADDR_NONE.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

inet_ntoa


inet_ntoa

The Windows Sockets inet_ntoa function converts an (Ipv4) Internet network address into a string in Internet standard dotted format.

char FAR * inet_ntoa (
  struct in_addr in
);

Parameters

in
[in] A structure that represents an Internet host address.

Remarks

The inet_ntoa function takes an Internet address structure specified by the in parameter and returns an ASCII string representing the address in ".'' (dot) notation as in "a.b.c.d''. The string returned by inet_ntoa resides in memory that is allocated by Windows Sockets. The application should not make any assumptions about the way in which the memory is allocated. The data is guaranteed to be valid until the next Windows Sockets function call within the same thread, but no longer. Therefore, the data should be copied before another Windows Sockets call is made.

Return Values

If no error occurs, inet_ntoa returns a char pointer to a static buffer containing the text address in standard ".'' notation. Otherwise, it returns NULL.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

inet_addr


ioctlsocket

The Windows Sockets ioctlsocket function controls the I/O mode of a socket.

int ioctlsocket (
  SOCKET s,
  long cmd,
  u_long FAR* argp
);

Parameters

s
[in] A descriptor identifying a socket.
cmd
[in] The command to perform on the socket s.
argp
[in/out] A pointer to a parameter for cmd.

Remarks

The ioctlsocket function can be used on any socket in any state. It is used to set or retrieve operating parameters associated with the socket, independent of the protocol and communications subsystem. Here are the supported commands to use in the cmd parameter and their semantics:

FIONBIO
Use with a nonzero argp parameter to enable the nonblocking mode of socket s. The argp parameter is zero if nonblocking is to be disabled. The argp parameter points to an unsigned long value. When a socket is created, it operates in blocking mode by default (nonblocking mode is disabled). This is consistent with BSD sockets.

The WSAAsyncSelect and WSAEventSelect functions automatically set a socket to nonblocking mode. If WSAAsyncSelect or WSAEventSelect has been issued on a socket, then any attempt to use ioctlsocket to set the socket back to blocking mode will fail with WSAEINVAL. To set the socket back to blocking mode, an application must first disable WSAAsyncSelect by calling WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect by calling WSAEventSelect with the lNetworkEvents parameter equal to zero.

FIONREAD
Use to determine the amount of data pending in the network's input buffer that can be read from socket s. The argp parameter points to an unsigned long value in which ioctlsocket stores the result. If s is stream oriented (for example, type SOCK_STREAM), FIONREAD returns the amount of data that can be read in a single call to the recv function; this might not be the same as the total amount of data queued on the socket. If s is message oriented (for example, type SOCK_DGRAM), FIONREAD returns the size of the first datagram (message) queued on the socket.
SIOCATMARK
Use to determine whether or not all out-of-band data has been read. (See section Windows Sockets 1.1 Blocking Routines & EINPROGRESS for a discussion on Out of Band (OOB) data.) This applies only to a stream oriented socket (for example, type SOCK_STREAM) that has been configured for in-line reception of any out-of-band data (SO_OOBINLINE). If no out-of-band data is waiting to be read, the operation returns TRUE. Otherwise, it returns FALSE, and the next recv or recvfrom performed on the socket will retrieve some or all of the data preceding the "mark." The application should use the SIOCATMARK operation to determine whether any data remains. If there is any normal data preceding the "urgent" (out of band) data, it will be received in order. (A recv or recvfrom will never mix out-of-band and normal data in the same call.) The argp parameter points to an unsigned long value in which ioctlsocket stores the boolean result.

Compatibility

This ioctlsocket function performs only a subset of functions on a socket when compared to the ioctl function found in Berkeley sockets. The ioctlsocket function has no command parameter equivalent to the FIOASYNC of ioctl, and SIOCATMARK is the only socket-level command that is supported by ioctlsocket.

Return Values

Upon successful completion, the ioctlsocket returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor s is not a socket.
WSAEFAULT | The argp parameter is not a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getsockopt, setsockopt, socket, WSAAsyncSelect, WSAEventSelect, WSAIoctl


listen

The Windows Sockets listen function places a socket a state where it is listening for an incoming connection.

int listen (
  SOCKET s,
  int backlog
);

Parameters

s
[in] A descriptor identifying a bound, unconnected socket.
backlog
[in] The maximum length of the queue of pending connections. If this value is SOMAXCONN, then the underlying service provider responsible for socket s will set the backlog to a maximum "reasonable" value. There is no standard provision to find out the actual backlog value.

Remarks

To accept connections, a socket is first created with the socket function and bound to a local address with the bind function, a backlog for incoming connections is specified with listen, and then the connections are accepted with the accept function. Sockets that are connection oriented, those of type SOCK_STREAM for example, are used with listen. The socket s is put into "passive'' mode where incoming connection requests are acknowledged and queued pending acceptance by the process.

The listen function is typically used by servers that can have more than one connection request at a time. If a connection request arrives and the queue is full, the client will receive an error with an indication of WSAECONNREFUSED.

If there are no available socket descriptors, listen attempts to continue to function. If descriptors become available, a later call to listen or accept will refill the queue to the current or most recent "backlog'', if possible, and resume listening for incoming connections.

An application can call listen more than once on the same socket. This has the effect of updating the current backlog for the listening socket. Should there be more pending connections than the new backlog value, the excess pending connections will be reset and dropped.

Windows CE: As in 4.3BSD, illegal values (less than 1 or greater than 5) are replaced by the nearest valid value.

For IrSockets implementation:

  • The Af_irda.h file must be explicitly included.
  • The WSAENETDOWN return value is not supported.
  • The backlog parameter is currently limited (silently) to 2.

Compatibility

The backlog parameter is limited (silently) to a reasonable value as determined by the underlying service provider. Illegal values are replaced by the nearest legal value. There is no standard provision to find out the actual backlog value.

Return Values

If no error occurs, listen returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs during execution of the bind function, but could be delayed until this function if the bind was to a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be "committed" at the time of this function.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | The socket has not been bound with bind.
WSAEISCONN | The socket is already connected.
WSAEMFILE | No more socket descriptors are available.
WSAENOBUFS | No buffer space is available.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The referenced socket is not of a type that supports the listen operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, connect, socket


ntohl

The Windows Sockets ntohl function converts a u_long from TCP/IP network order to host byte order (which is big-endian).

u_long ntohl (
  u_long netlong
);

Parameters

netlong
[in] A 32-bit number in TCP/IP network byte order.

Remarks

The ntohl function takes a 32-bit number in TCP/IP network byte order and returns a 32-bit number in host byte order.

Return Values

The ntohl function always returns a value in host byte order. If the netlong parameter was already in host byte order, then no operation is performed.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

htonl, htons, ntohs, WSAHtonl, WSAHtons, WSANtohl, WSANtohs


ntohs

The Windows Sockets ntohs function converts a u_short from TCP/IP network byte order to host byte order (which is big-endian).

u_short ntohs (
  u_short netshort
);

Parameters

netshort
[in] A 16-bit number in TCP/IP network byte order.

Remarks

The ntohs function takes a 16-bit number in TCP/IP network byte order and returns a 16-bit number in host byte order.

Return Values

The ntohs function returns the value in host byte order. If the netshort parameter was already in host byte order, then no operation is performed.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

htonl, htons, ntohl, WSAHtonl, WSAHtons, WSANtohl, WSANtohs


recv

The Windows Sockets recv function receives data from a connected socket.

int recv (
  SOCKET s,
  char FAR* buf,
  int len,
  int flags
);

Parameters

s
[in] A descriptor identifying a connected socket.
buf
[out] A buffer for the incoming data.
len
[in] The length of buf.
flags
[in] A flag specifying the way in which the call is made.

Remarks

The recv function is used to read incoming data on connection-oriented sockets, or connectionless sockets. When using a connection-oriented protocol, the sockets must be connected before calling recv. When using a connectionless protocol, the sockets must be bound before calling recv.

The local address of the socket must be known. For server applications, use an explicit bind function or an implicit accept or WSAAccept function. Explicit binding is discouraged for client applications. For client applications the socket can become bound implicitly to a local address using connect, WSAConnect, sendto, WSASendTo, or WSAJoinLeaf.

For connected or connectionless sockets, this function restricts the addresses from which received messages are accepted. The function only returns messages from the remote address specified in the connection. Messages from other addresses are (silently) discarded

For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much information as is currently available—up to the size of the buffer supplied. If the socket has been configured for in-line reception of out-of-band data (socket option SO_OOBINLINE) and out-of-band data is yet unread, only out-of-band data will be returned. The application can use the ioctlsocket or WSAIoctl SIOCATMARK command to determine whether any more out-of-band data remains to be read.

For connectionless sockets (type SOCK_DGRAM or other message-oriented sockets), data is extracted from the first enqueued datagram (message) from the destination address specified by the connect function.

If the datagram or message is larger than the buffer supplied, the buffer is filled with the first part of the datagram, and recv generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost; for reliable protocols, the data is retained by the service provider until it is successfully read by calling recv with a large enough buffer. For TCP/IP, an application cannot receive from any multicast address until after becoming a group member.

If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect functions can be used to determine when more data arrives.

If the socket is connection oriented and the remote side has shut down the connection gracefully, and all data has been received, a recv will complete immediately with zero bytes received. If the connection has been reset, a recv will fail with the error WSAECONNRESET.

The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. The semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or'ing the following values:

Value | Meaning
MSG_PEEK | Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function then returns the number of bytes currently pending to receive.
MSG_OOB | Process out-of-band data. (See section DECnet Out-Of-band data for a discussion of this topic.)

Return Values

If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The buf parameter is not completely contained in a valid part of the user address space.
WSAENOTCONN | The socket is not connected.
WSAEINTR | The (blocking) call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENETRESET | The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to recv on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the receive operation would block.
WSAEMSGSIZE | The message was too large to fit into the specified buffer and was truncated.
WSAEINVAL | The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled or (for byte stream sockets only) len was zero or negative.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.
WSAETIMEDOUT | The connection has been dropped because of a network failure or because the peer system failed to respond.
WSAECONNRESET | The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. The application should close the socket as it is no longer usable. On a UDP datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

recvfrom, select, send, socket, WSAAsyncSelect, WSARecvEx


recvfrom

The Windows Sockets recvfrom function receives a datagram and stores the source address.

int recvfrom (
  SOCKET s,
  char FAR* buf,
  int len,
  int flags,
  struct sockaddr FAR* from,
  int FAR* fromlen
);

Parameters

s
[in] A descriptor identifying a bound socket.
buf
[out] A buffer for the incoming data.
len
[in] The length of buf.
flags
[in] An indicator specifying the way in which the call is made.
from
[out] An optional pointer to a buffer that will hold the source address upon return.
fromlen
[in/out] An optional pointer to the size of the from buffer.

Remarks

The recvfrom function reads incoming data on both connected and unconnected sockets and captures the address from which the data was sent. The socket must not be connected. The local address of the socket must be known. For server applications, this is usually done explicitly through bind. Explicit binding is discouraged for client applications. For client applications using this function, the socket can become bound implicitly to a local address through sendto, WSASendTo, or WSAJoinLeaf.

For stream oriented sockets such as those of type SOCK_STREAM, a call to recvfrom returns as much information as is currently available—up to the size of the buffer supplied. If the socket has been configured for in-line reception of out-of-band data (socket option SO_OOBINLINE) and out-of-band data is yet unread, only out-of-band data will be returned. The application can use the ioctlsocket or WSAIoctl SIOCATMARK command to determine whether any more out-of-band data remains to be read. The from and fromlen parameters are ignored for connection-oriented sockets.

For message-oriented sockets, data is extracted from the first enqueued message, up to the size of the buffer supplied. If the datagram or message is larger than the buffer supplied, the buffer is filled with the first part of the datagram, and recvfrom generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost.

If the from paramter is nonzero and the socket is not connection oriented, (type SOCK_DGRAM for example), the network address of the peer that sent the data is copied to the corresponding SOCKADDR structure. The value pointed to by fromlen is initialized to the size of this structure and is modified, on return, to indicate the actual size of the address stored in the SOCKADDR structure.

If no incoming data is available at the socket, the recvfrom function blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect can be used to determine when more data arrives.

If the socket is connection oriented and the remote side has shut down the connection gracefully, the call to recvfrom will complete immediately with zero bytes received. If the connection has been reset recvfrom will fail with the error WSAECONNRESET.

The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. The semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or-ing the following values:

Value | Meaning
MSG_PEEK | Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue, and the function returns the number of bytes currently pending to receive.
MSG_OOB | Process out-of-band data. (See section DECnet Out-Of-band data for a discussion of this topic.)

Return Values

If no error occurs, recvfrom returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The buf or from parameters are not part of the user address space, or the fromlen parameter is too small to accommodate the peer address.
WSAEINTR | The (blocking) call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative.
WSAEISCONN | The socket is connected. This function is not permitted with a connected socket, whether the socket is connection-oriented or connectionless.
WSAENETRESET | The connection has been broken due to the "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to recvfrom on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the recvfrom operation would block.
WSAEMSGSIZE | The message was too large to fit into the specified buffer and was truncated.
WSAETIMEDOUT | The connection has been dropped, because of a network failure or because the system on the other end went down without notice.
WSAECONNRESET | The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. The application should close the socket as it is no longer usable. On a UDP datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

recv, send, socket, WSAAsyncSelect, WSAEventSelect


select

The Windows Sockets select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.

int select (
  int nfds,
  fd_set FAR * readfds,
  fd_set FAR * writefds,
  fd_set FAR * exceptfds,
  const struct timeval FAR * timeout
);

Parameters

nfds
[in] This parameter is ignored; it is included only for compatibility with Berkeley sockets.
readfds
[in/out] An optional pointer to a set of sockets to be checked for readability.
writefds
[in/out] An optional pointer to a set of sockets to be checked for writability
exceptfds
[in/out] An optional pointer to a set of sockets to be checked for errors.
timeout
[in] The maximum time for select to wait, or NULL for blocking operation.

Remarks

The select function is used to determine the status of one or more sockets. For each socket, the caller can request information on read, write or error status. The set of sockets for which a given status is requested is indicated by an FD_SET structure. The sockets contained within the FD_SET structures must be associated with a single service provider. For the purpose of this restriction, sockets are considered to be from the same service provider if the WSAPROTOCOL_INFO structures describing their protocols have the same providerId value. Upon return, the structures are updated to reflect the subset of these sockets that meet the specified condition. The select function returns the number of sockets meeting the conditions. A set of macros is provided for manipulating an FD_SET structure. These macros are compatible with those used in the Berkeley software, but the underlying representation is completely different.

The parameter readfds identifies the sockets that are to be checked for readability. If the socket is currently in the listen state, it will be marked as readable if an incoming connection request has been received such that an accept is guaranteed to complete without blocking. For other sockets, readability means that queued data is available for reading such that a call to recv, WSARecv, WSARecvFrom, or recvfrom is guaranteed not to block.

For connection-oriented sockets, readability can also indicate that a request to close the socket has been received from the peer. If the virtual circuit was closed gracefully, and all data was received, then a recv will return immediately with zero bytes read. If the virtual circuit was reset, then a recv will complete immediately with an error code such as WSAECONNRESET. The presence of out-of-band data will be checked if the socket option SO_OOBINLINE has been enabled (see setsockopt).

The parameter writefds identifies the sockets that are to be checked for writability. If a socket is processing a connect call (nonblocking), a socket is writable if the connection establishment successfully completes. If the socket is not processing a connect call, writability means a send, sendto, or WSASendto are guaranteed to succeed. However, they can block on a blocking socket if the len parameter exceeds the amount of outgoing system buffer space available. It is not specified how long these guarantees can be assumed to be valid, particularly in a multithreaded environment.

The parameter exceptfds identifies the sockets that are to be checked for the presence of out-of-band data (see section DECnet Out-Of-band data for a discussion of this topic) or any exceptional error conditions.

Important Out-of-band data will only be reported in this way if the option SO_OOBINLINE is FALSE. If a socket is processing a connect call (nonblocking), failure of the connect attempt is indicated in exceptfds (application must then call getsockopt SO_ERROR to determine the error value to describe why the failure occurred). This document does not define which other errors will be included.

Any two of the parameters, readfds, writefds, or exceptfds, can be given as NULL. At least one must be non-NULL, and any non-NULL descriptor set must contain at least one handle to a socket.

Summary: A socket will be identified in a particular set when select returns if:

readfds:

  • If listen has been called and a connection is pending, accept will succeed
  • Data is available for reading (includes OOB data if SO_OOBINLINE is enabled)
  • Connection has been closed/reset/terminated

writefds:

  • If processing a connect call (nonblocking), connection has succeeded
  • Data can be sent

exceptfds:

  • If processing a connect call (nonblocking), connection attempt failed
  • OOB data is available for reading (only if SO_OOBINLINE is disabled)

Four macros are defined in the header file WINSOCK2.H for manipulating and checking the descriptor sets. The variable FD_SETSIZE determines the maximum number of descriptors in a set. (The default value of FD_SETSIZE is 64, which can be modified by defining FD_SETSIZE to another value before including WINSOCK2.H.) Internally, socket handles in an FD_SET structure are not represented as bit flags as in Berkeley Unix. Their data representation is opaque. Use of these macros will maintain software portability between different socket environments. The macros to manipulate and check FD_SET contents are:

FD_CLR(s, *set)
Removes the descriptor s from set.
FD_ISSET(s, *set)
Nonzero if s is a member of the set. Otherwise, zero.
FD_SET(s, *set)
Adds descriptor s to set.
FD_ZERO(*set)
Initializes the set to the NULL set.

The parameter timeout controls how long the select can take to complete. If timeout is a null pointer, select will block indefinitely until at least one descriptor meets the specified criteria. Otherwise, timeout points to a TIMEVAL structure that specifies the maximum time that select should wait before returning. When select returns, the contents of the TIMEVAL structure are not altered. If TIMEVAL is initialized to {0, 0}, select will return immediately; this is used to "poll" the state of the selected sockets. If select returns immediately, then the select call is considered nonblocking and the standard assumptions for nonblocking calls apply. For example, the blocking hook will not be called, and Windows Sockets will not yield.

Note The select function has no effect on the persistence of socket events registered with WSAAsyncSelect or WSAEventSelect.

Return Values

The select function returns the total number of socket handles that are ready and contained in the FD_SET structures, zero if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError can be used to retrieve a specific error code.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAEFAULT | The Windows Sockets implementation was unable to allocate needed resources for its internal operations, or the readfds, writefds, exceptfds, or timeval parameters are not part of the user address space.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | The timeout value is not valid, or all three descriptor parameters were NULL.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | One of the descriptor sets contains an entry that is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, connect, recv, recvfrom, send, WSAAsyncSelect, WSAEventSelect


send

The Windows Sockets send function sends data on a connected socket.

int send (
  SOCKET s,
  const char FAR * buf,
  int len,
  int flags
);

Parameters

s
[in] A descriptor identifying a connected socket.
buf
[in] A buffer containing the data to be transmitted.
len
[in] The length of the data in buf.
flags
[in] An indicator specifying the way in which the call is made.

Remarks

The send function is used to write outgoing data on a connected socket. For message-oriented sockets, care must be taken not to exceed the maximum packet size of the underlying provider, which can be obtained by using getsockopt to retrieve the value of socket option SO_MAX_MSG_SIZE. If the data is too long to pass atomically through the underlying protocol, the error WSAEMSGSIZE is returned, and no data is transmitted.

The successful completion of a send does not indicate that the data was successfully delivered.

If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in a nonblocking mode. On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both client and server machines. The select, WSAAsyncSelect or WSAEventSelect functions can be used to determine when it is possible to send more data.

Calling send with a zero len parameter is permissible and will be treated by implementations as successful. In such cases, send will return zero as a valid value. For message-oriented sockets, a zero-length transport datagram is sent.

The flags parameter can be used to influence the behavior of the function beyond the options specified for the associated socket. The semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or-ing the following values:

Value | Meaning
MSG_DONTROUTE | Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
MSG_OOB | Send out-of-band data (stream-style socket such as SOCK_STREAM only. Also see DECnet Out-Of-band data for a discussion of this topic).

Windows CE: For IrSockets implementation, the Af_irda.h file must be explicitly included.

Return Values

If no error occurs, send returns the total number of bytes sent, which can be less than the number indicated by len for nonblocking sockets. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEACCES | The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST parameter to allow the use of the broadcast address.
WSAEINTR | A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The buf parameter is not completely contained in a valid part of the user address space.
WSAENETRESET | The connection has been broken due to the "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOBUFS | No buffer space is available.
WSAENOTCONN | The socket is not connected.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to send on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the requested operation would block.
WSAEMSGSIZE | The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
WSAEHOSTUNREACH | The remote host cannot be reached from this host at this time.
WSAEINVAL | The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.
WSAECONNRESET | The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. For UPD sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the socket as it is no longer usable.
WSAETIMEDOUT | The connection has been dropped, because of a network failure or because the system on the other end went down without notice.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

recv, recvfrom, select, sendto, socket, WSAAsyncSelect, WSAEventSelect


sendto

The Windows Sockets sendto function sends data to a specific destination.

int sendto (
  SOCKET s,
  const char FAR * buf,
  int len,
  int flags,
  const struct sockaddr FAR * to,
  int tolen
);

Parameters

s
[in] A descriptor identifying a (possibly connected) socket.
buf
[in] A buffer containing the data to be transmitted.
len
[in] The length of the data in buf.
flags
[in] An indicator specifying the way in which the call is made.
to
[in] An optional pointer to the address of the target socket.
tolen
[in] The size of the address in to.

Remarks

The sendto function is used to write outgoing data on a socket. For message-oriented sockets, care must be taken not to exceed the maximum packet size of the underlying subnets, which can be obtained by using getsockopt to retrieve the value of socket option SO_MAX_MSG_SIZE. If the data is too long to pass atomically through the underlying protocol, the error WSAEMSGSIZE is returned and no data is transmitted.

The to parameter can be any valid address in the socket's address family, including a broadcast or any multicast address. To send to a broadcast address, an application must have used setsockopt with SO_BROADCAST enabled. Otherwise, sendto will fail with the error code WSAEACCES. For TCP/IP, an application can send to any multicast address (without becoming a group member).

If the socket is unbound, unique values are assigned to the local association by the system, and the socket is then marked as bound. An application can use getsockname to determine the local socket name in this case.

The successful completion of a sendto does not indicate that the data was successfully delivered.

The sendto function is normally used on a connectionless socket to send a datagram to a specific peer socket identified by the to parameter. Even if the connectionless socket has been previously connected to a specific address, the to parameter overrides the destination address for that particular datagram only. On a connection-oriented socket, the to and tolen parameters are ignored, making sendto equivalent to send.

For sockets using IP (version 4):

To send a broadcast (on a SOCK_DGRAM only), the address in the to parameter should be constructed using the special IP address INADDR_BROADCAST (defined in WINSOCK2.H), together with the intended port number. It is generally inadvisable for a broadcast datagram to exceed the size at which fragmentation can occur, which implies that the data portion of the datagram (excluding headers) should not exceed 512 bytes.

If no buffer space is available within the transport system to hold the data to be transmitted, sendto will block unless the socket has been placed in a nonblocking mode. On nonblocking, stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server systems. The select, WSAAsyncSelect or WSAEventSelect function can be used to determine when it is possible to send more data.

Calling sendto with a len of zero is permissible and will return zero as a valid value. For message-oriented sockets, a zero-length transport datagram is sent.

The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. The semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or-ing the following values:

Value | Meaning
MSG_DONTROUTE | Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
MSG_OOB | Send out-of-band data (stream-style socket such as SOCK_STREAM only. Also see DECnet Out-Of-band data for a discussion of this topic.)

Return Values

If no error occurs, sendto returns the total number of bytes sent, which can be less than the number indicated by len. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEACCES | The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST parameter to allow the use of the broadcast address.
WSAEINVAL | An unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.
WSAEINTR | A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The buf or to parameters are not part of the user address space, or the tolen parameter is too small.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOBUFS | No buffer space is available.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only)
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to sendto on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the requested operation would block.
WSAEMSGSIZE | The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
WSAEHOSTUNREACH | The remote host cannot be reached from this host at this time.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.
WSAECONNRESET | The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. For UPD sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the socket as it is no longer usable.
WSAEADDRNOTAVAIL | The remote address is not a valid address, for example, ADDR_ANY.
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAEDESTADDRREQ | A destination address is required.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAETIMEDOUT | The connection has been dropped, because of a network failure or because the system on the other end went down without notice.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

recv, recvfrom, select, send, socket, WSAAsyncSelect, WSAEventSelect


SetService

Important The SetService function is obsolete. For the convenience of Windows Sockets 1.1 developers, the reference material is below.

The functions detailed in Protocol-Independent Name Resolution provide equivalent functionality in Windows Sockets 2.

The SetService function registers or deregisters a network service within one or more name spaces. The function can also add or remove a network service type within one or more name spaces.

INT SetService(
  DWORD dwNameSpace,  // specifies name space(s) to operate within
  DWORD dwOperation,  // specifies operation to perform
  DWORD dwFlags,      // set of bit flags that modify function
                      // operation
  LPSERVICE_INFO lpServiceInfo,
                      // points to structure containing service
                      // information
  LPSERVICE_ASYNC_INFO lpServiceAsyncInfo,
                      // reserved for future use, must be NULL
  LPDWORD lpdwStatusFlags
                      // points to set of status bit flags
);

Parameters

dwNameSpace
The name space, or a set of default name spaces, within which the function will operate.

Use one of the following constants to specify a name space:
Value | Name Space
NS_DEFAULT | A set of default name spaces. The function queries each name space within this set. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set. NS_DEFAULT is the value that most applications should use for dwNameSpace.
NS_DNS | The Domain Name System used in the Internet to resolve the name of the host.
NS_NDS | The NetWare 4 provider.
NS_NETBT | The NetBIOS over TCP/IP layer. All Windows NT and Windows 95 systems register their computer names with NetBIOS. This name space is used to convert a computer name to an IP address that uses this registration.
NS_SAP | The NetWare Service Advertising Protocol. This can access the Netware bindery, if appropriate. NS_SAP is a dynamic name space that enables the registration of services.
NS_TCPIP_HOSTS | Lookup value in the <systemroot>\system32\drivers\etc\posts file.
NS_TCPIP_LOCAL | Local TCP/IP name resolution mechanisms, including comparisons against the local host name and lookup value in the cache of host to IP address mappings.

dwOperation
Specifies the operation that the function will perform. Use one of the following values to specify an operation:
Value | Meaning
SERVICE_REGISTER | Register the network service with the name space. This operation can be used with the SERVICE_FLAG_DEFER and SERVICE_FLAG_HARD bit flags.
SERVICE_DEREGISTER | Deregister the network service from the name space. This operation can be used with the SERVICE_FLAG_DEFER and SERVICE_FLAG_HARD bit flags.
SERVICE_FLUSH | Perform any operation that was called with the SERVICE_FLAG_DEFER bit flag set to one.
SERVICE_ADD_TYPE Add a service type to the name space.

For this operation, use the ServiceSpecificInfo member of the SERVICE_INFO structure pointed to by lpServiceInfo to pass a SERVICE_TYPE_INFO_ABS structure. You must also set the ServiceType member of the SERVICE_INFO structure. Other SERVICE_INFO members are ignored.
SERVICE_DELETE_TYPE | Remove a service type, added by a previous call specifying the SERVICE_ADD_TYPE operation, from the name space.

dwFlags
A set of bit flags that modify the function's operation. You can set one or more of the following bit flags:
Value Name Space
SERVICE_FLAG_DEFER This bit flag is valid only if the operation is SERVICE_REGISTER or SERVICE_DEREGISTER.

If this bit flag is one, and it is valid, the name-space provider should defer the registration or deregistration operation until a SERVICE_FLUSH operation is requested.
SERVICE_FLAG_HARD This bit flag is valid only if the operation is SERVICE_REGISTER or SERVICE_DEREGISTER.

If this bit flag is one, and it is valid, the name-space provider updates any relevant persistent store information when the operation is performed.

For example: If the operation involves deregistration in a name space that uses a persistent store, the name-space provider would remove the relevant persistent store information.

lpService_Info
Points to a SERVICE_INFO structure that contains information about the network service or service type.
lpServiceAsyncInfo
This parameter is reserved for future use. It must be set to NULL.
lpdwStatusFlags
A set of bit flags that receive function status information. The following bit flag is defined:
Value | Meaning
SET_SERVICE_PARTIAL_SUCCESS | One or more name-space providers were unable to successfully perform the requested operation.

Return Values

If the function succeeds, the return value is not SOCKET_ERROR.

If the function fails, the return value is SOCKET_ERROR. To get extended error information, call GetLastError. GetLastError can return the following extended error value:

Value | Meaning
ERROR_ALREADY_REGISTERED | The function tried to register a service that was already registered.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.
Import Library: Link with wsock32.lib.

See Also

GetService, SERVICE_INFO, SERVICE_TYPE_INFO_ABS


setsockopt

The Windows Sockets setsockopt function sets a socket option.

int setsockopt (
  SOCKET s,
  int level,
  int optname,
  const char FAR * optval,
  int optlen
);

Parameters

s
[in] A descriptor identifying a socket.
level
[in] The level at which the option is defined; the supported levels include SOL_SOCKET and IPPROTO_TCP. See the Windows Sockets 2 Protocol-Specific Annex (a separate document included with the Platform SDK) for more information on protocol-specific levels.
optname
[in] The socket option for which the value is to be set.
optval
[in] A pointer to the buffer in which the value for the requested option is supplied.
optlen
[in] The size of the optval buffer.

Remarks

The setsockopt function sets the current value for a socket option associated with a socket of any type, in any state. Although options can exist at multiple protocol levels, they are always present at the uppermost "socket'' level. Options affect socket operations, such as whether expedited data (OOB data for example) is received in the normal data stream, and whether broadcast messages can be sent on the socket.

There are two types of socket options: Boolean options that enable or disable a feature or behavior, and options that require an integer value or structure. To enable a Boolean option, optval points to a nonzero integer. To disable the option optval points to an integer equal to zero. The optlen parameter should be equal to sizeof(int) for Boolean options. For other options, optval points to the an integer or structure that contains the desired value for the option, and optlen is the length of the integer or structure.

The following options are supported for setsockopt. For default values of these options, see the description. The Type identifies the type of data addressed by optval.

level = SOL_SOCKET

Value | Type | Meaning
SO_BROADCAST | BOOL | Allow transmission of broadcast messages on the socket.
SO_DEBUG | BOOL | Record debugging information.
SO_DONTLINGER | BOOL | Do not block close waiting for unsent data to be sent. Setting this option is equivalent to setting SO_LINGER with l_onoff set to zero.
SO_DONTROUTE | BOOL | Do not route: send directly to interface.
SO_GROUP_PRIORITY | int | Reserved for future use with socket groups. Specify the relative priority to be established for sockets that are part of a socket group.
SO_KEEPALIVE | BOOL | Send keepalives
SO_LINGER | struct LINGER | Linger on close if unsent data is present.
SO_OOBINLINE | BOOL | Receive out-of-band data in the normal data stream. (See section DECnet Out-Of-band data for a discussion of this topic.)
SO_RCVBUF | int | Specify the total per-socket buffer space reserved for receives. This is unrelated to SO_MAX_MSG_SIZE or the size of a TCP window.
SO_REUSEADDR | BOOL | Allow the socket to be bound to an address that is already in use. (See bind.)
SO_SNDBUF | int | Specify the total per-socket buffer space reserved for sends. This is unrelated to SO_MAX_MSG_SIZE or the size of a TCP window.
PVD_CONFIG | Service Provider Dependent | This object stores the configuration information for the service provider associated with socket s. The exact format of this data structure is service provider specific.

level = IPPROTO_TCP1

TCP_NODELAY BOOL Disables the Nagle algorithm for send coalescing.
1 included for backward compatibility with Windows Sockets 1.1

BSD options not supported for setsockopt are:

Value | Type | Meaning
SO_ACCEPTCONN | BOOL | Socket is listening
SO_RCVLOWAT | int | Receive low water mark
SO_RCVTIMEO | int | Receive time-out (available in Microsoft implementation of Windows Sockets 2)
SO_SNDLOWAT | int | Send low water mark
SO_SNDTIMEO | int | Send time-out (available in Microsoft implementation of Windows Sockets 2)
SO_TYPE | int | Type of the socket

SO_DEBUG
Windows Sockets service providers are encouraged (but not required) to supply output debug information if the SO_DEBUG option is set by an application. The mechanism for generating the debug information and the form it takes are beyond the scope of this document.
SO_GROUP_PRIORITY
Reserved for future use with socket groups. Group priority indicates the relative priority of the specified socket relative to other sockets within the socket group. Values are non-negative integers, with zero corresponding to the highest priority. Priority values represent a hint to the underlying service provider about how potentially scarce resources should be allocated. For example, whenever two or more sockets are both ready to transmit data, the highest priority socket (lowest value for SO_GROUP_PRIORITY) should be serviced first with the remainder serviced in turn according to their relative priorities.

The WSAENOPROTOOPT error is indicated for nongroup sockets or for service providers that do not support group sockets.

SO_KEEPALIVE
An application can request that a TCP/IP provider enable the use of "keep-alive" packets on TCP connections by turning on the SO_KEEPALIVE socket option. A Windows Sockets provider need not support the use of keep-alives. If it does, the precise semantics are implementation-specific but should conform to section 4.2.3.6 of RFC 1122: Requirements for Internet Hosts — Communication Layers. If a connection is dropped as the result of "keep-alives" the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN.
SO_LINGER
The SO_LINGER option controls the action taken when unsent data is queued on a socket and a closesocket is performed. See closesocket for a description of the way in which the SO_LINGER settings affect the semantics of closesocket. The application sets the desired behavior by creating a LINGER structure (pointed to by the optval parameter) with these members l_onoff and l_linger set appropriately.
SO_REUSEADDR
By default, a socket cannot be bound (see bind) to a local address that is already in use. On occasion, however, it can be necessary to "re-use" an address in this way. Since every connection is uniquely identified by the combination of local and remote addresses, there is no problem with having two sockets bound to the same local address as long as the remote addresses are different. To inform the Windows Sockets provider that a bind on a socket should not be disallowed because the desired address is already in use by another socket, the application should set the SO_REUSEADDR socket option for the socket before issuing the bind. The option is interpreted only at the time of the bind. It is therefore unnecessary and harmless to set the option on a socket that is not to be bound to an existing address. Setting or resetting the option after the bind has no effect on this or any other socket.
SO_RCVBUF and SO_SNDBUF
When a Windows Sockets implementation supports the SO_RCVBUF and SO_SNDBUF options, an application can request different buffer sizes (larger or smaller). The call to setsockopt can succeed even when the implementation did not provide the whole amount requested. An application must call getsockopt with the same option to check the buffer size actually provided.
PVD_CONFIG
This object stores the configuration information for the service provider associated with the socket specified in the s parameter. The exact format of this data structure is specific to each service provider.
TCP_NODELAY
The TCP_NODELAY option is specific to TCP/IP service providers. The Nagle algorithm is disabled if the TCP_NODELAY option is enabled (and vice versa). The process involves buffering send data when there is unacknowledged data already "in flight" or buffering send data until a full-size packet can be sent. It is highly recommended that TCP/IP service providers enable the Nagle Algorithm by default, and for the vast majority of application protocols the Nagle Algorithm can deliver significant performance enhancements. However, for some applications this algorithm can impede performance, and TCP_NODELAY can be used to turn it off. These are applications where many small messages are sent, and the time delays between the messages are maintained. Application writers should not set TCP_NODELAY unless the impact of doing so is well-understood and desired because setting TCP_NODELAY can have a significant negative impact on network and application performance.

Windows CE: The SO_RCVBUF option is not supported. If you attempt to use this option setsockopt returns WSAEOPNOTSUPP.

To set the socket to secure mode, the option level parameter, level, must set to SO_SOCKET, the option name, optname to SO_SECURE, and the option value, optval, must be a pointer to a DWORD containing SO_SEC_SSL. These settings ensure that the Unified Secure Sockets Layer (SSL) package be used. For example,

DWORD optval = SO_SEC_SSL;
err = setsockopt(
    Socket,
    SOL_SOCKET,
    SO_SECURE,
    &optval,
    sizeof(optval)
    );.

In addition to the normal error values, the setsockopt function can return an additional error code, namely, WSAEISCONN, to signify that the socket can not switch to secure mode once it has been connected.

When used in the context of SSL, the WSAENOPROTOOP error code acquires additional meaning, to indicate that the option level does not equal to SO_SOCKET.

For IrSocket implementation, Af_irda.h must be explicitly included.

The WSAENETDOWN return value is not supported for IrSockets.

IrSockets provides two settable socket options:

Value | Type | Meaning
IRLMP_IAS_SET | * IAS_SET | Sets IAS attributes.
IRLMP_IRLPT_MODE | * int | In non-zero, enables IrLPT mode for printing to IrDA printers.

The IRLMP_IAS_SET socket option allows the application to set a single attribute of a single class in the local IAS. The application specifies the class to set and the attribute and attribute type. It is expected that the application allocate a buffer of the necessary size for the passed parameters.

The IRLMP_RAW_MODE socket option allows the application to switch between TinyTP mode and unreliable IrLMP mode. If it is not set, IrSockets are assumed to use TinyTP. This option is only available after issuing the socket function and before issuing any other Windows Sockets function.

Many SO_ level socket options are not meaningful to IrSockets. Only SO_LINGER is specifically supported.

Return Values

If no error occurs, setsockopt returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | optval is not in a valid part of the process address space or optlen parameter is too small.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | level is not valid, or the information in optval is not valid.
WSAENETRESET | Connection has timed out when SO_KEEPALIVE is set.
WSAENOPROTOOPT | The option is unknown or unsupported for the specified provider or socket (see SO_GROUP_PRIORITY limitations).
WSAENOTCONN | Connection has been reset when SO_KEEPALIVE is set.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

bind, getsockopt, ioctlsocket, socket, WSAAsyncSelect, WSAEventSelect


shutdown

The Windows Sockets shutdown function disables sends or receives on a socket.

int shutdown (
  SOCKET s,
  int how
);

Parameters

s
[in] A descriptor identifying a socket.
how
[in] A flag that describes what types of operation will no longer be allowed.

Remarks

The shutdown function is used on all types of sockets to disable reception, transmission, or both.

If the how parameter is SD_RECEIVE, subsequent calls to the recv function on the socket will be disallowed. This has no effect on the lower protocol layers. For TCP sockets, if there is still data queued on the socket waiting to be received, or data arrives subsequently, the connection is reset, since the data cannot be delivered to the user. For UDP sockets, incoming datagrams are accepted and queued. In no case will an ICMP error packet be generated.

If the how parameter is SD_SEND, subsequent calls to the send function are disallowed. For TCP sockets, a FIN will be sent after all data is sent and acknowledged by the receiver.

Setting how to SD_BOTH disables both sends and receives as described above.

The shutdown function does not close the socket. Any resources attached to the socket will not be freed until closesocket is invoked.

To assure that all data is sent and received on a connected socket before it is closed, an application should use shutdown to close connection before calling closesocket. For example, to initiate a graceful disconnect:

  1. Call WSAAsyncSelect to register for FD_CLOSE notification.
  2. Call shutdown with how=SD_SEND.
  3. When FD_CLOSE received, call recv until zero returned, or SOCKET_ERROR.
  4. Call closesocket.

Note The shutdown function does not block regardless of the SO_LINGER setting on the socket.

An application should not rely on being able to re-use a socket after it has been shut down. In particular, a Windows Sockets provider is not required to support the use of connect on a socket that has been shutdown.

Return Values

If no error occurs, shutdown returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | The how parameter is not valid, or is not consistent with the socket type. For example, SD_SEND is used with a UNI_RECV socket type.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only).
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

connect, socket


socket

The Windows Sockets socket function creates a socket that is bound to a specific service provider.

SOCKET socket (
  int af,
  int type,
  int protocol
);

Parameters

af
[in] An address family specification.
type
[in] A type specification for the new socket.

The following are the only two type specifications supported for Windows Sockets 1.1:
Type | Explanation
SOCK_STREAM | Provides sequenced, reliable, two-way, connection-based byte streams with an out-of-band data transmission mechanism. Uses TCP for the Internet address family.
SOCK_DGRAM | Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses UDP for the Internet address family.

In Windows Sockets 2, many new socket types will be introduced and don' need to be specified now because an application can dynamically discover the attributes of each available transport protocol through the WSAEnumProtocols function. Socket type definitions will appear in WINSOCK2.H, which will be periodically updated as new socket types, address families and protocols are defined.

protocol
[in] A particular protocol to be used with the socket that is specific to the indicated address family.

Remarks

The socket function causes a socket descriptor and any related resources to be allocated and bound to a specific transport service provider. Windows Sockets will utilize the first available service provider that supports the requested combination of address family, socket type and protocol parameters. The socket that is created will have the overlapped attribute as a default. For Microsoft operating systems, the Microsoft-specific socket option, SO_OPENTYPE, defined in MSWSOCK.H can affect this default. See Microsoft-specific documentation for a detailed description of SO_OPENTYPE. Sockets without the overlapped attribute can be created by using WSASocket. All functions that allow overlapped operation (WSASend, WSARecv,WSASendTo, WSARecvFrom, and WSAIoctl) also support non-overlapped usage on an overlapped socket if the values for parameters related to overlapped operation are NULL.

When selecting a protocol and its supporting service provider this procedure will only choose a base protocol or a protocol chain, not a protocol layer by itself. Unchained protocol layers are not considered to have partial matches on type or af either. That is, they do not lead to an error code of WSAEAFNOSUPPORT or WSAEPROTONOSUPPORT if no suitable protocol is found.

Important The manifest constant AF_UNSPEC continues to be defined in the header file but its use is strongly discouraged, as this can cause ambiguity in interpreting the value of the protocol parameter.

Connection-oriented sockets such as SOCK_STREAM provide full-duplex connections, and must be in a connected state before any data can be sent or received on it. A connection to another socket is created with a connect call. Once connected, data can be transferred using send and recv calls. When a session has been completed, a closesocket must be performed.

The communications protocols used to implement a reliable, connection-oriented socket ensure that data is not lost or duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT.

Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using sendto and recvfrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer using send and can be received only from this peer using recv.

Support for sockets with type RAW is not required, but service providers are encourage to support raw sockets whenever it makes sense to do so.

Windows CE: Windows CE supports the PF_INET and AF_IRDA ARPA Internet address formats.

To use IrSock, set the af parameter to AF_IRDA and set the protocol parameter to NULL.

Windows CE supports SOCK_STREAM and SOCK_DCRAM socket types.

Return Values

If no error occurs, socket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem or the associated service provider has failed.
WSAEAFNOSUPPORT | The specified address family is not supported.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEMFILE | No more socket descriptors are available.
WSAENOBUFS | No buffer space is available. The socket cannot be created.
WSAEPROTONOSUPPORT | The specified protocol is not supported.
WSAEPROTOTYPE | The specified protocol is the wrong type for this socket.
WSAESOCKTNOSUPPORT | The specified socket type is not supported in this address family.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, bind, connect, getsockname, getsockopt, ioctlsocket, listen, recv, recvfrom, select, send, sendto, setsockopt, shutdown, WSASocket


TransmitFile

Notice This function is a Microsoft-specific extension to the Windows Sockets specification. For more information, see Microsoft Extensions and Windows Sockets 2.

The Windows Sockets TransmitFile function transmits file data over a connected socket handle. This function uses the operating system's cache manager to retrieve the file data, and provides high-performance file data transfer over sockets.

BOOL TransmitFile(
  SOCKET hSocket,
  HANDLE hFile,
  DWORD nNumberOfBytesToWrite,
  DWORD nNumberOfBytesPerSend,
  LPOVERLAPPED lpOverlapped,
  LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
  DWORD dwFlags
);

Parameters

hSocket
A handle to a connected socket. The function will transmit the file data over this socket.

The socket specified by hSocket must be a connection-oriented socket.

Sockets of type SOCK_STREAM, SOCK_SEQPACKET, or SOCK_RDM are connection-oriented sockets. The TransmitFile function does not support datagram sockets.

hFile
A handle to an open file. The function transmits this file's data. The operating system reads the file data sequentially. You can improve caching performance by opening the handle with the FILE_FLAG_SEQUENTIAL_SCAN.
nNumberOfBytesToWrite
The number of bytes to transmit. The function completes when it has sent this many bytes, or if an error occurs.

Set this parameter to zero to transmit the entire file.

nNumberOfBytesPerSend
The size of each block of data sent per send operation. This specification is for use by the sockets layer of the operating system.

Set this parameter to zero to have the sockets layer select a default send size.

This parameter is useful for message protocols that have limitations on the size of individual send requests.

lpOverlapped
Pointer to an OVERLAPPED structure. If the socket handle has been opened as overlapped, specify this parameter in order to achieve an overlapped (aysnchronous) I/O operation. By default, socket handles are opened as overlapped.

You can use lpOverlapped to specify an offset within the file at which to start the file data transfer by setting the Offset and OffsetHigh member of the OVERLAPPED structure. If lpOverlapped is NULL, the transmission of data always starts at the current byte offset in the file.

When lpOverlapped is not NULL, the overlapped I/O might not finish before TransmitFile returns. In that case, the TransmitFile function returns FALSE, and GetLastError returns ERROR_IO_PENDING. This lets the caller continue processing while the file transmission operation completes. The operating system will set the event specified by the hEvent member of the OVERLAPPED structure, or the socket specified by hSocket, to the signaled state upon completion of the data transmission request.

lpTransmitBuffers
Pointer to a TRANSMIT_FILE_BUFFERS data structure that contains pointers to data to send before and after the file data is sent. Set this parameter to NULL if you only want to transmit the file data.
dwFlags
An attribute that has three settings:
TF_DISCONNECT
Start a transport-level disconnect after all the file data has been queued for transmission.
TF_REUSE_SOCKET
Prepare the socket handle to be reused. When the TransmitFile request completes, the socket handle can be passed to the AcceptEx function. It is only valid if TF_DISCONNECT is also specified.
TF_WRITE_BEHIND
Complete the TransmitFile request immediately, without pending. If this flag is specified and TransmitFile succeeds, then the data has been accepted by the system but not necessarily acknowledged by the remote end. If TransmitFile returns TRUE, there will be no completion port indication for the I/O. Do not use this setting with the other two settings.

Return Values

If the TransmitFile function succeeds, the return value is TRUE. Otherwise, the return value is FALSE. To get extended error information, call GetLastError. The function returns FALSE if an overlapped I/O operation is not complete before TransmitFile returns. In that case, GetLastError returns ERROR_IO_PENDING.

Remarks

The Windows NT Server optimizes the TransmitFile function for high performance. The Windows NT Workstation optimizes the function for minimum memory and resource utilization. Expect better performance results when using TransmitFile on Windows NT Server.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in mswsock.h.
Import Library: Link with mswsock.lib.


WSAAccept

The Windows Sockets WSAAccept function conditionally accepts a connection based on the return value of a condition function, optionally creates or joins a socket group, provides QOS flowspecs, and allows transfer of connection data.

SOCKET WSAAccept (
  SOCKET s,
  struct sockaddr FAR * addr,
  LPINT addrlen,
  LPCONDITIONPROC lpfnCondition,
  DWORD dwCallbackData
);

Parameters

s
[in] A descriptor identifying a socket that is listening for connections after a call to the listen function.
addr
[out] An optional pointer to a buffer that receives the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family established when the socket was created.
addrlen
[in/out] An optional pointer to an integer that contains the length of the address addr.
lpfnCondition
[in] The procedure instance address of the optional, application-supplied condition function that will make an accept/reject decision based on the caller information passed in as parameters, and optionally create or join a socket group by assigning an appropriate value to the result parameter g of this function.
dwCallbackData
[in] The callback data passed back to the application as the value of the dwCallbackData parameter of the condition function. This parameter is not interpreted by Windows Sockets.

Remarks

The WSAAccept function extracts the first connection on the queue of pending connections on socket s, and checks it against the condition function, provided the condition function is specified (that is, not NULL). If the condition function returns CF_ACCEPT, WSAAccept creates a new socket and performs any socket grouping as indicated by the result parameter g in the condition function. The newly created socket has the same properties as socket s including asynchronous events registered with WSAAsyncSelect or with WSAEventSelect, but not including the listening socket's group ID, if any. If the condition function returns CF_REJECT, WSAAccept rejects the connection request. The condition function runs in the same thread as this function does, and should return as soon as possible. If the decision cannot be made immediately, the condition function should return CF_DEFER to indicate that no decision has been made, and no action about this connection request should be taken by the service provider. When the application is ready to take action on the connection request, it will invoke WSAAccept again and return either CF_ACCEPT or CF_REJECT as a return value from the condition function.

A socket in the default mode (blocking) will block until a connection is present when an application calls WSAAccept and no connections are pendng on the queue.

A socket in the nonblocking mode (blocking) fails with the error WSAEWOULDBLOCK when an application calls WSAAccept and no connections are pendng on the queue. After WSAAccept succeeds and returns a new socket handle, the accepted socket cannot be used to accept any more connections. The original socket remains open and listens for new connection requests.

The addr parameter is a result parameter that is filled in with the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family in which the communication is occurring. The addrlen is a value-result parameter; it should initially contain the amount of space pointed to by addr. On return, it will contain the actual length (in bytes) of the address returned. This call is used with connection-oriented socket types such as SOCK_STREAM. If addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned. Otherwise, these two parameters will be filled in regardless of whether the condition function is specified or what it returns.

A prototype of the condition function is as follows:

int CALLBACK ConditionFunc(
  IN LPWSABUF lpCallerId,
  IN LPWSABUF lpCallerData,
  IN OUT LPQOS lpSQOS,
  IN OUT LPQOS lpGQOS,
  IN LPWSABUF lpCalleeId,
  OUT LPWSABUF lpCalleeData,
  OUT GROUP FAR * g,
  IN DWORD dwCallbackData
);

The ConditionFunc is a placeholder for the application-supplied callback function. The actual condition function must reside in a DLL or application module. It is exported in the module definition file. Use MakeProcInstance to get a procedure-instance address for the callback function.

The lpCallerId parameter is a value parameter that contains the address of the connecting entity. The lpCallerData is a value parameter that contains any user data. The information in these parameters is sent along with the connection request. If no caller identification or caller data is available, the corresponding parameters will be NULL. Many network protocols do not support connect-time caller data. Most conventional network protocols can be expected to support caller ID information at connection-request time. The buf portion of the WSABUF pointed to by lpCallerId points to a SOCKADDR. The SOCKADDR is interpreted according to its address family (typically by casting the SOCKADDR to some type specific to the address family).

The lpSQOS parameter references the FLOWSPEC structures for socket s specified by the caller, one for each direction, followed by any additional provider-specific parameters. The sending or receiving flow specification values will be ignored as appropriate for any unidirectional sockets. A NULL value for indicates that there is no caller supplied QOS and that no negotiation is possible. A non-NULL lpSQOS pointer indicates that a QOS negotiation is to occur or that the provider is prepared to accept the QOS request without negotiation.

The lpGQOS parameter (reserved for future use with socket groups) references the FLOWSPEC structures for the socket group the caller is to create, one for each direction, followed by any additional provider-specific parameters. A NULL value for lpGQOS indicates no caller-supplied group quality of service. quality of service information can be returned if negotiation is to occur.

The lpCalleeId is a value parameter that contains the local address of the connected entity. The buf portion of the WSABUF pointed to by lpCalleeId points to a SOCKADDR. The SOCKADDR is interpreted according to its address family (typically by casting the SOCKADDR to some type specific to the address family).

The lpCalleeData is a result parameter used by the condition function to supply user data back to the connecting entity. The lpCalleeData->len initially contains the length of the buffer allocated by the service provider and pointed to by lpCalleeData->buf. A value of zero means passing user data back to the caller is not supported. The condition function should copy up to lpCalleeData->len bytes of data into lpCalleeData->buf, and then update lpCalleeData->len to indicate the actual number of bytes transferred. If no user data is to be passed back to the caller, the condition function should set lpCalleeData->len to zero. The format of all address and user data is specific to the address family to which the socket belongs.

Reserved for future use with socket groups: The result parameter g is assigned within the condition function to indicate the following actions:

  1. if &g is an existing socket group ID, add s to this group, provided all the requirements set by this group are met; or
  2. if &g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket group and have s as the first member; or
  3. if &g = SG_CONSTRAINED_GROUP, create a constrained socket group and have s as the first member; or
  4. if &g = zero, no group operation is performed.

For unconstrained groups, any set of sockets can be grouped together as long as they are supported by a single service provider. A constrained socket group can consist only of connection-oriented sockets, and requires that connections on all grouped sockets be to the same address on the same host. For newly created socket groups, the new group ID can be retrieved by using getsockopt with option SO_GROUP_ID, if this operation completes successfully. A socket group and its associated ID remain valid until the last socket belonging to this socket group is closed. Socket group IDs are unique across all processes for a given service provider.

The dwCallbackData parameter value passed to the condition function is the value passed as the dwCallbackData parameter in the original WSAAccept call. This value is interpreted only by the Windows Socket version 2 client. This allows a client to pass some context information from the WSAAccept call site through to the condition function. This also provides the condition function with any additional information required to determine whether to accept the connection or not. A typical usage is to pass a (suitably cast) pointer to a data structure containing references to application-defined objects with which this socket is associated.

Return Values

If no error occurs, WSAAccept returns a value of type SOCKET that is a descriptor for the accepted socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.

The integer referred to by addrlen initially contains the amount of space pointed to by addr. On return it will contain the actual length in bytes of the address returned.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAECONNREFUSED | The connection request was forcefully rejected as indicated in the return value of the condition function (CF_REJECT).
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The addrlen parameter is too small or the addr or lpfnCondition are not part of the user address space.
WSAEINTR | A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress.
WSAEINVAL | listen was not invoked prior to WSAAccept, parameter g specified in the condition function is not a valid value, the source address of the incoming connection request is not consistent with that of the constrained group the parameter g is referring to, the return value of the condition function is not a valid one, or any case where the specified socket is in an invalid state.
WSAEMFILE | The queue is nonempty upon entry to WSAAccept and there are no socket descriptors available.
WSAENOBUFS | No buffer space is available.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The referenced socket is not a type that supports connection-oriented service.
WSATRY_AGAIN | The acceptance of the connection request was deferred as indicated in the return value of the condition function (CF_DEFER).
WSAEWOULDBLOCK | The socket is marked as nonblocking and no connections are present to be accepted.
WSAEACCES | The connection request that was offered has timed out or been withdrawn.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, bind, connect, getsockopt, listen, select, socket, WSAAsyncSelect, WSAConnect


WSAAddressToString

The Windows Sockets WSAAddressToString function converts all components of a SOCKADDR structure into a human-readable string representation of the address.

This is intended to be used mainly for display purposes. If the caller wants the translation to be done by a particular provider, it should supply the corresponding WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.

INT WSAAddressToString(
  LPSOCKADDR lpsaAddress,
  DWORD dwAddressLength,
  LPWSAPROTOCOL_INFO lpProtocolInfo,
  OUT LPTSTR lpszAddressString,
  IN OUT LPDWORD lpdwAddressStringLength
);

Parameters

lpsaAddress
[in] A pointer to the SOCKADDR structure to translate into a string.
dwAddressLength
[in] The length of the address in SOCKADDR,which may vary in size with different protocols.
lpProtocolInfo
[in] (Optional) The WSAPROTOCOL_INFO structure for a particular provider. If this is NULL, the call is routed to the provider of the first protocol supporting the address family indicated in lpsaAddress.
lpszAddressString
[in] A buffer that receives the human-readable address string.
lpdwAddressStringLength
[in/out] On input, the length of the AddressString buffer. On output, returns the length of the string actually copied into the buffer. If the supplied buffer is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated with the required size in bytes.

Return Values

If no error occurs, WSAAddressToString returns a value of zero. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSAEFAULT | The specified lpcsAddress, lpProtocolInfo, lpszAddressString are not all in the address space of the process, or the lpszAddressString buffer is too small. Pass in a larger buffer.
WSAEINVAL | The specified address is not a valid socket address, or there was no transport provider supporting its indicated address family.
WSANOTINITIALIZED | The Winsock 2 DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSAAsyncGetHostByAddr

The Windows Sockets WSAAsyncGetHostByAddr function asynchronously retrieves host information that corresponds to an address.

HANDLE WSAAsyncGetHostByAddr (
  HWND hWnd,
  unsigned int wMsg,
  const char FAR * addr,
  int len,
  int type,
  char FAR * buf,
  int buflen
);

Parameters

hWnd
[in] The handle of the window that will receive a message when the asynchronous request completes.
wMsg
[in] The message to be received when the asynchronous request completes.
addr
[in] A pointer to the network address for the host. Host addresses are stored in network byte order.
len
[in] The length of the address.
type
[in] The type of the address.
buf
[out] A pointer to the data area to receive the HOSTENT data. The data area must be larger than the size of a HOSTENT structure because the supplied data area is used by Windows Sockets to contain a HOSTENT structure and all of the data referenced by members of the HOSTENT structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
buflen
[in] The size of data area for the buf parameter.

Remarks

The WSAAsyncGetHostByAddr function is an asynchronous version of gethostbyaddr. It is used to retrieve the host name and address information that corresponds to a network address. Windows Sockets initiates the operation and returns to the caller immediately, passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation has completed, the application window indcated by the hWnd parameter receives message in the wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code can be any error as defined in WINSOCK2.H. An error code of zero indicates successful completion of the asynchronous operation.

On successful completion, the buffer supplied to the original function call contains a HOSTENT structure. To access the members of this structure, the original buffer address is cast to a HOSTENT structure pointer and accessed as appropriate.

If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the requisite information. If the application decides that the partial data is inadequate, it can reissue the WSAAsyncGetHostByAddr function call with a buffer large enough to receive all the desired information (that is, no smaller than the low 16 bits of lParam).

The buffer supplied to this function is used by Windows Sockets to construct a structure together with the contents of data areas referenced by members of the same HOSTENT structure. To avoid the WSAENOBUFS error, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in WINSOCK2.H).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in WINSOCK2.H as:

#define WSAGETASYNCERROR(lParam)            HIWORD(lParam)
#define WSAGETASYNCBUFLEN(lParam)           LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Values

The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or failure of the operation itself.

If no error occurs, WSAAsyncGetHostByAddr returns a nonzero value of type HANDLE that is the asynchronous task handle (not to be confused with a Windows HTASK) for the request. This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages by examining the wParam message parameter.

If the asynchronous operation could not be initiated, WSAAsyncGetHostByAddr returns a zero value, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

The following error codes can be set when an application window receives a message. As described above, they can be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN | The network subsystem has failed.
WSAENOBUFS | Insufficient buffer space is available.
WSAEFAULT | addr or buf is not in a valid part of the process address space.
WSAHOST_NOT_FOUND | Authoritative Answer Host not found.
WSATRY_AGAIN | Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY | Nonrecoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA | Valid name, no data record of requested type.

The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEWOULDBLOCK | The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

gethostbyaddr, HOSTENT, WSACancelAsyncRequest


WSAAsyncGetHostByName

The Windows Sockets WSAAsyncGetHostByName function asynchronously retrieves host information corresponding to a host name.

HANDLE WSAAsyncGetHostByName (
  HWND hWnd,
  unsigned int wMsg,
  const char FAR * name,
  char FAR * buf,
  int buflen
);

Parameters

hWnd
[in] The handle of the window that will receive a message when the asynchronous request completes.
wMsg
[in] The message to be received when the asynchronous request completes.
name
[in] A pointer to the null-terminated name of the host.
buf
[out] A pointer to the data area to receive the HOSTENT data. The data area must be larger than the size of a HOSTENT structure because the supplied data area is used by Windows Sockets to contain a HOSTENT structure and all of the data referenced by members of the HOSTENT structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
buflen
[in] The size of data area for the buf parameter.

Remarks

The WSAAsyncGetHostByName function is an asynchronous version of gethostbyname, and is used to retrieve host name and address information corresponding to a host name. Windows Sockets initiates the operation and returns to the caller immediately, passing back an opaque "asynchronous task handle" that whichthe application can use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation has completed, the application window indcated by the hWnd parameter receives message in the wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code can be any error as defined in WINSOCK2.H. An error code of zero indicates successful completion of the asynchronous operation.

On successful completion, the buffer supplied to the original function call contains a HOSTENT structure. To access the elements of this structure, the original buffer address should be cast to a HOSTENT structure pointer and accessed as appropriate.

If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the requisite information. If the application decides that the partial data is inadequate, it can reissue the WSAAsyncGetHostByAddr function call with a buffer large enough to receive all the desired information (that is, no smaller than the low 16 bits of lParam).

The buffer supplied to this function is used by Windows Sockets to construct a HOSTENT structure together with the contents of data areas referenced by members of the same HOSTENT structure. To avoid the WSAENOBUFS error, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in WINSOCK2.H).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in WINSOCK2.H as:

#define WSAGETASYNCERROR(lParam)            HIWORD(lParam)
#define WSAGETASYNCBUFLEN(lParam)           LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

WSAAsyncGetHostByName is guaranteed to resolve the string returned by a successful call to gethostname.

Return Values

The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or failure of the operation itself.

If no error occurs, WSAAsyncGetHostByName returns a nonzero value of type HANDLE that is the asynchronous task handle (not to be confused with a Windows HTASK) for the request. This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages by examining the wParam message parameter.

If the asynchronous operation could not be initiated, WSAAsyncGetHostByName returns a zero value, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

The following error codes can be set when an application window receives a message. As described above, they can be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN | The network subsystem has failed.
WSAENOBUFS | Insufficient buffer space is available.
WSAEFAULT | The name or buf parameter is not in a valid part of the process address space.
WSAHOST_NOT_FOUND | Authoritative Answer Host not found.
WSATRY_AGAIN | Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY | Nonrecoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA | Valid name, no data record of requested type.

The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEWOULDBLOCK | The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

gethostbyname, HOSTENT, WSACancelAsyncRequest


WSAAsyncGetProtoByName

The Windows Sockets WSAAsyncGetProtoByName function gets protocol information corresponding to a protocol name asynchronously.

HANDLE WSAAsyncGetProtoByName (
  HWND hWnd,
  unsigned int wMsg,
  const char FAR * name,
  char FAR * buf,
  int buflen
);

Parameters

hWnd
[in] The handle of the window that will receive a message when the asynchronous request completes.
wMsg
[in] The message to be received when the asynchronous request completes.
name
[in] A pointer to the null-terminated protocol name to be resolved.
buf
[out] A pointer to the data area to receive the PROTOENT data. The data area must be larger than the size of a PROTOENT structure because the data area is used by Windows Sockets to contain a PROTOENT structure and all of the data that is referenced by members of the PROTOENT structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
buflen
[out] The size of data area for the buf parameter.

Remarks

The WSAAsyncGetProtoByName function is an asynchronous version of getprotobyname. It is used to retrieve the protocol name and number from the Windows Sockets database corresponding to given protocol name. Windows Sockets initiates the operation and returns to the caller immediately, passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation has completed, the application window indcated by the hWnd parameter receives message in the wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code can be any error as defined in WINSOCK2.H. An error code of zero indicates successful completion of the asynchronous operation.

On successful completion, the buffer supplied to the original function call contains a PROTOENT structure. To access the members of this structure, the original buffer address should be cast to a PROTOENT structure pointer and accessed as appropriate.

If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the requisite information. If the application decides that the partial data is inadequate, it can reissue the WSAAsyncGetHostByAddr function call with a buffer large enough to receive all the desired information (that is, no smaller than the low 16 bits of lParam).

The buffer supplied to this function is used by Windows Sockets to construct a PROTOENT structure together with the contents of data areas referenced by members of the same PROTOENT structure. To avoid the WSAENOBUFS error noted above, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in WINSOCK2.H).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in WINSOCK2.H as:

#define WSAGETASYNCERROR(lParam)            HIWORD(lParam)
#define WSAGETASYNCBUFLEN(lParam)           LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Values

The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or failure of the operation itself.

If no error occurs, WSAAsyncGetProtoByName returns a nonzero value of type HANDLE that is the asynchronous task handle for the request (not to be confused with a Windows HTASK). This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages, by examining the wParam message parameter.

If the asynchronous operation could not be initiated, WSAAsyncGetProtoByName returns a zero value, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

The following error codes can be set when an application window receives a message. As described above, they can be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN | The network subsystem has failed.
WSAENOBUFS | Insufficient buffer space is available.
WSAEFAULT | The name or buf parameter is not in a valid part of the process address space.
WSAHOST_NOT_FOUND | Authoritative Answer Protocol not found.
WSATRY_AGAIN | Non-Authoritative Protocol not found, or server failure.
WSANO_RECOVERY | Nonrecoverable errors, the protocols database is not accessible.
WSANO_DATA | Valid name, no data record of requested type.

The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEWOULDBLOCK | The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getprotobyname, WSACancelAsyncRequest


WSAAsyncGetProtoByNumber

The Windows Sockets WSAAsyncGetProtoByNumber function asynchronously retrieves protocol information corresponding to a protocol number.

HANDLE WSAAsyncGetProtoByNumber (
  HWND hWnd,
  unsigned int wMsg,
  int number,
  char FAR * buf,
  int buflen
);

Parameters

hWnd
[in] The handle of the window that will receive a message when the asynchronous request completes.
wMsg
[in] The message to be received when the asynchronous request completes.
number
[in] The protocol number to be resolved, in host byte order.
buf
[out] A pointer to the data area to receive the PROTOENT data. The data area must be larger than the size of a PROTOENT structure because the data area is used by Windows Sockets to contain a PROTOENT structure and all of the data that is referenced by members of the PROTOENT structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
buflen
[in] The size of data area for the buf parameter.

Remarks

The WSAAsyncGetProtoByNumber function is an asynchronous version of getprotobynumber, and is used to retrieve the protocol name and number corresponding to a protocol number. Windows Sockets initiates the operation and returns to the caller immediately, passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation has completed, the application window indcated by the hWnd parameter receives message in the wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code can be any error as defined in WINSOCK2.H. An error code of zero indicates successful completion of the asynchronous operation.

On successful completion, the buffer supplied to the original function call contains a PROTOENT structure. To access the members of this structure, the original buffer address is cast to a PROTOENT structure pointer and accessed as appropriate.

If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the requisite information. If the application decides that the partial data is inadequate, it can reissue the WSAAsyncGetHostByAddr function call with a buffer large enough to receive all the desired information (that is, no smaller than the low 16 bits of lParam).

The buffer supplied to this function is used by Windows Sockets to construct a PROTOENT structure together with the contents of data areas referenced by members of the same PROTOENT structure. To avoid the WSAENOBUFS error noted above, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in WINSOCK2.H).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in WINSOCK2.H as:

#define WSAGETASYNCERROR(lParam)            HIWORD(lParam)
#define WSAGETASYNCBUFLEN(lParam)           LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Values

The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or failure of the operation itself.

If no error occurs, WSAAsyncGetProtoByNumber returns a nonzero value of type HANDLE that is the asynchronous task handle for the request (not to be confused with a Windows HTASK). This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages, by examining the wParam message parameter.

If the asynchronous operation could not be initiated, WSAAsyncGetProtoByNumber returns a zero value, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

The following error codes can be set when an application window receives a message. As described above, they can be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN | The network subsystem has failed.
WSAENOBUFS | Insufficient buffer space is available.
WSAEFAULT | The buf paramater is not in a valid part of the process address space.
WSAHOST_NOT_FOUND | Authoritative Answer Protocol not found.
WSATRY_AGAIN | Non-Authoritative Protocol not found, or server failure.
WSANO_RECOVERY | Nonrecoverable errors, the protocols database is not accessible.
WSANO_DATA | Valid name, no data record of requested type.

The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEWOULDBLOCK | The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getprotobynumber, WSACancelAsyncRequest


WSAAsyncGetServByName

The Windows Sockets WSAAsyncGetServByName function asynchronously retrieves service information corresponding to a service name and port.

HANDLE WSAAsyncGetServByName (
  HWND hWnd,
  unsigned int wMsg,
  const char FAR * name,
  const char FAR * proto,
  char FAR * buf,
  int buflen
);

Parameters

hWnd
[in] The handle of the window that should receive a message when the asynchronous request completes.
wMsg
[in] The message to be received when the asynchronous request completes.
name
[in] A pointer to a null-terminated service name.
proto
[in] A pointer to a protocol name. This can be NULL, in which case WSAAsyncGetServByName will search for the first service entry for which s_name or one of the s_aliases matches the given name. Otherwise, WSAAsyncGetServByName matches both name and proto.
buf
[out] A pointer to the data area to receive the SERVENT data. The data area must be larger than the size of a SERVENT structure because the data area supplied is used by Windows Sockets to contain a SERVENT structure and all of the data that is referenced by members of the SERVENT structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
buflen
[in] The size of data area for the buf parameter.

Remarks

The WSAAsyncGetServByName function is an asynchronous version of getservbyname and is used to retrieve service information corresponding to a service name. Windows Sockets initiates the operation and returns to the caller immediately, passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation has completed, the application window indcated by the hWnd parameter receives message in the wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code can be any error as defined in WINSOCK2.H. An error code of zero indicates successful completion of the asynchronous operation.

On successful completion, the buffer supplied to the original function call contains a SERVENT structure. To access the members of this structure, the original buffer address should be cast to a SERVENT structure pointer and accessed as appropriate.

If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the requisite information. If the application decides that the partial data is inadequate, it can reissue the WSAAsyncGetHostByAddr function call with a buffer large enough to receive all the desired information (that is, no smaller than the low 16 bits of lParam).

The buffer supplied to this function is used by Windows Sockets to construct a SERVENT structure together with the contents of data areas referenced by members of the same SERVENT structure. To avoid the WSAENOBUFS error, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in WINSOCK2.H).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in WINSOCK2.H as:

#define WSAGETASYNCERROR(lParam)            HIWORD(lParam)
#define WSAGETASYNCBUFLEN(lParam)           LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Values

The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or failure of the operation itself.

If no error occurs, WSAAsyncGetServByName returns a nonzero value of type HANDLE that is the asynchronous task handle for the request (not to be confused with a Windows HTASK). This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages, by examining the wParam message parameter.

If the asynchronous operation could not be initiated, WSAAsyncServByName returns a zero value, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

The following error codes can be set when an application window receives a message. As described above, they can be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN | The network subsystem has failed.
WSAENOBUFS | Insufficient buffer space is available.
WSAEFAULT | buf is not in a valid part of the process address space.
WSAHOST_NOT_FOUND | Authoritative Answer Host not found.
WSATRY_AGAIN | Non-Authoritative Service not found, or server failure.
WSANO_RECOVERY | Nonrecoverable errors, the services database is not accessible.
WSANO_DATA | Valid name, no data record of requested type.

The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEWOULDBLOCK | The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getservbyname, WSACancelAsyncRequest


WSAAsyncGetServByPort

The Windows Sockets WSAAsyncGetServByPort function gets service information corresponding to a port and protocol asynchronously.

HANDLE WSAAsyncGetServByPort (
  HWND hWnd,
  unsigned int wMsg,
  int port,
  const char FAR * proto,
  char FAR * buf,
  int buflen
);

Parameters

hWnd
[in] The handle of the window that should receive a message when the asynchronous request completes.
wMsg
[in] The message to be received when the asynchronous request completes.
port
[in] The port for the service, in network byte order.
proto
[in] A pointer to a protocol name. This can be NULL, in which case WSAAsyncGetServByPort will search for the first service entry for which s_port match the given port. Otherwise, WSAAsyncGetServByPort matches both port and proto.
buf
[out] pointer to the data area to receive the SERVENT data. The data area must be larger than the size of a SERVENT structure because the data area supplied is used by Windows Sockets to contain a SERVENT structure and all of the data that is referenced by members of the SERVENT structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
buflen
[in] The size of data area for the buf parameter.

Remarks

The WSAAsyncGetServByPort function is an asynchronous version of getservbyport, and is used to retrieve service information corresponding to a port number. Windows Sockets initiates the operation and returns to the caller immediately, passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation has completed, the application window indcated by the hWnd parameter receives message in the wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code can be any error as defined in WINSOCK2.H. An error code of zero indicates successful completion of the asynchronous operation.

On successful completion, the buffer supplied to the original function call contains a SERVENT structure. To access the members of this structure, the original buffer address should be cast to a SERVENT structure pointer and accessed as appropriate.

If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the requisite information. If the application decides that the partial data is inadequate, it can reissue the WSAAsyncGetHostByAddr function call with a buffer large enough to receive all the desired information (that is, no smaller than the low 16 bits of lParam).

The buffer supplied to this function is used by Windows Sockets to construct a SERVENT structure together with the contents of data areas referenced by members of the same SERVENT structure. To avoid the WSAENOBUFS error, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in WINSOCK2.H).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in WINSOCK2.H as:

#define WSAGETASYNCERROR(lParam)            HIWORD(lParam)
#define WSAGETASYNCBUFLEN(lParam)           LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Values

The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or failure of the operation itself.

If no error occurs, WSAAsyncGetServByPort returns a nonzero value of type HANDLE that is the asynchronous task handle for the request (not to be confused with a Windows HTASK). This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages, by examining the wParam message parameter.

If the asynchronous operation could not be initiated, WSAAsyncGetServByPort returns a zero value, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

The following error codes can be set when an application window receives a message. As described above, they can be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN | The network subsystem has failed.
WSAENOBUFS | Insufficient buffer space is available.
WSAEFAULT | proto or buf is not in a valid part of the process address space.
WSAHOST_NOT_FOUND | Authoritative Answer Port not found.
WSATRY_AGAIN | Non-Authoritative Port not found, or server failure.
WSANO_RECOVERY | Nonrecoverable errors, the services database is not accessible.
WSANO_DATA | Valid name, no data record of requested type.

The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEWOULDBLOCK | The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getservbyport, WSACancelAsyncRequest


WSAAsyncSelect

The Windows Sockets WSAAsyncSelect function requests Windows message-based notification of network events for a socket.

int WSAAsyncSelect (
  SOCKET s,
  HWND hWnd,
  unsigned int wMsg,
  long lEvent
);

Parameters

s
[in] A descriptor identifying the socket for which event notification is required.
hWnd
[in] A handle identifying the window that will receive a message when a network event occurs.
wMsg
[in] The message to be received when a network event occurs.
lEvent
[in] A bitmask that specifies a combination of network events in which the application is interested.

Remarks

The WSAAsyncSelect function is used to request that WS2_32.DLL should send a message to the window hWnd whenever it detects any of the network events specified by the lEvent parameter. The message that should be sent is specified by the wMsg parameter. The socket for which notification is required is identified by the s parameter.

The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of lEvent. See the ioctlsocket functions for information on how to set the nonblocking socket back to blocking mode.

The lEvent parameter is constructed by using the bitwise OR operator with any of the values specified in the following list.

Value | Meaning
FD_READ | Want to receive notification of readiness for reading
FD_WRITE | Want to receive notification of readiness for writing
FD_OOB | Want to receive notification of the arrival of out-of-band data
FD_ACCEPT | Want to receive notification of incoming connections
FD_CONNECT | Want to receive notification of completed connection or multi-point join operation
FD_CLOSE | Want to receive notification of socket closure
FD_QOS | Want to receive notification of socket Quality of Service (QOS) changes
FD_GROUP_QOS | Want to receive notification of socket group Quality of Service (QOS) changes (reserved for future use with socket groups)
FD_ROUTING _INTERFACE_CHANGE | Want to receive notification of routing interface changes for the specified destination(s)
FD_ADDRESS_LIST _CHANGE | Want to receive notification of local address list changes for the socket's protocol family

Issuing a WSAAsyncSelect for a socket cancels any previous WSAAsyncSelect or WSAEventSelect for the same socket. For example, to receive notification for both reading and writing, the application must call WSAAsyncSelect with both FD_READ and FD_WRITE, as follows:

rc = WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE);

It is not possible to specify different messages for different events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE events will be reported with message wMsg2:

rc = WSAAsyncSelect(s, hWnd, wMsg1, FD_READ);
rc = WSAAsyncSelect(s, hWnd, wMsg2, FD_WRITE);

To cancel all notification indicating that Windows Sockets should send no further messages related to network events on the socket, lEvent is set to zero.

rc = WSAAsyncSelect(s, hWnd, 0, 0);

Although WSAAsyncSelect immediately disables event message posting for the socket in this instance, it is possible that messages could be waiting in the application's message queue. Therefore, the application must be prepared to receive network event messages even after cancellation. Closing a socket with closesocket also cancels WSAAsyncSelect message sending, but the same caveat about messages in the queue still applies.

The socket created by the accept function has the same properties as the listening socket used to accept it. Consequently, WSAAsyncSelect events set for the listening socket also apply to the accepted socket. For example, if a listening socket has WSAAsyncSelect events FD_ACCEPT, FD_READ, and FD_WRITE, then any socket accepted on that listening socket will also have FD_ACCEPT, FD_READ, and FD_WRITE events with the same wMsg value used for messages. If a different wMsg or events are desired, the application should call WSAAsyncSelect, passing the accepted socket and the desired new information.

When one of the nominated network events occurs on the specified socket s, the application's window hWnd receives message wMsg. The wParam parameter identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code. The error code be any error as defined in WINSOCK2.H.

Note Upon receipt of an event notification message, the WSAGetLastError function cannot be used to check the error value because the error value returned can differ from the value in the high word of lParam.

The error and event codes can be extracted from the lParam using the macros WSAGETSELECTERROR and WSAGETSELECTEVENT, defined in WINSOCK2.H as:

#define WSAGETSELECTERROR(lParam)       HIWORD(lParam)
#define WSAGETSELECTEVENT(lParam)       LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

The possible network event codes that can be returned are as follows:

Value | Meaning
FD_READ | Socket s ready for reading
FD_WRITE | Socket s ready for writing
FD_OOB | Out-of-band data ready for reading on socket s
FD_ACCEPT | Socket s ready for accepting a new incoming connection
FD_CONNECT | Connection or multi-point join operation initiated on socket s completed
FD_CLOSE | Connection identified by socket s has been closed
FD_QOS | Quality of Service associated with socket s has changed
FD_GROUP_QOS | Quality of Service associated with the socket group to which s belongs has changed (reserved for future use with socket groups)
FD_ROUTING _INTERFACE_CHANGE | Local interface that should be used to send to the specified destination has changed
FD_ADDRESS_LIST _CHANGE | The list of addresses of the socket's protocol family to which the application client can bind has changed

Although WSAAsyncSelect can be called with interest in multiple events, the application window will receive a single message for each network event.

As in the case of the select function, WSAAsyncSelect will frequently be used to determine when a data transfer operation (send or recv) can be issued with the expectation of immediate success. Nevertheless, a robust application must be prepared for the possibility that it can receive a message and issue a Windows Sockets 2 call that returns WSAEWOULDBLOCK immediately. For example, the following sequence of events is possible:

  1. data arrives on socket s; Windows Sockets 2 posts WSAAsyncSelect message
  2. application processes some other message
  3. while processing, application issues an ioctlsocket(s, FIONREAD...) and notices that there is data ready to be read
  4. application issues a recv(s,...) to read the data
  5. application loops to process next message, eventually reaching the WSAAsyncSelect message indicating that data is ready to read
  6. application issues recv(s,...), which fails with the error WSAEWOULDBLOCK.

Other sequences are possible.

The WS2_32.DLL will not continually flood an application with messages for a particular network event. Having successfully posted notification of a particular event to an application window, no further message(s) for that network event will be posted to the application window until the application makes the function call that implicitly re-enables notification of that network event.

Event | Re-enabling function
FD_READ | recv, recvfrom, WSARecv, or WSARecvFrom
FD_WRITE | send, sendto, WSASend, or WSASendTo
FD_OOB | recv, recvfrom, WSARecv, or WSARecvFrom
FD_ACCEPT | accept or WSAAccept unless the error code is WSATRY_AGAIN indicating that the condition function returned CF_DEFER
FD_CONNECT | NONE
FD_CLOSE | NONE
FD_QOS | WSAIoctl with command SIO_GET_QOS
FD_GROUP_QOS | WSAIoctl with command SIO_GET_GROUP_QOS (reserved for future use with socket groups)
FD_ROUTING _INTERFACE_CHANGE | WSAIoctl with command SIO_ROUTING_INTERFACE_CHANGE
FD_ADDRESS_LIST _CHANGE | WSAIoctl with command SIO_ADDRESS_LIST_CHANGE

Any call to the re-enabling routine, even one that fails, results in re-enabling of message posting for the relevant event.

For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is "level-triggered." This means that if the re-enabling routine is called and the relevant condition is still met after the call, a WSAAsyncSelect message is posted to the application. This allows an application to be event-driven and not be concerned with the amount of data that arrives at any one time. Consider the following sequence:

  1. Network transport stack receives 100 bytes of data on socket s and causes Windows Sockets 2 to post an FD_READ message.
  2. The application issues recv( s, buffptr, 50, 0) to read 50 bytes.
  3. Another FD_READ message is posted since there is still data to be read.

With these semantics, an application need not read all available data in response to an FD_READ message—a single recv in response to each FD_READ message is appropriate. If an application issues multiple recv calls in response to a single FD_READ, it can receive multiple FD_READ messages. Such an application can need to disable FD_READ messages before starting the recv calls by calling WSAAsyncSelect with the FD_READ event not set.

The FD_QOS and FD_GROUP_QOS events are considered "edge triggered." A message will be posted exactly once when a quality of service change occurs. Further messages will not be forthcoming until either the provider detects a further change in quality of service or the application renegotiates the quality of service for the socket.

The FD_ROUTING_INTERFACE_CHANGE message is posted when the local interface that should be used to reach the destination specified in WSAIoctl with SIO_ROUTING_INTERFACE_CHANGE changes after such IOCTL has been issued.

The FD_ADDRESS_LIST_CHANGE message is posted when the list of addresses to which the application can bind changes after WSAIoctl with SIO_ADDRESS_LIST_CHANGE has been issued.

If any event has already happened when the application calls WSAAsyncSelect or when the re-enabling function is called, then a message is posted as appropriate. For example, consider the following sequence:

  1. an application calls listen,
  2. a connect request is received but not yet accepted,
  3. the application calls WSAAsyncSelect specifying that it wants to receive FD_ACCEPT messages for the socket. Due to the persistence of events, Windows Sockets 2 posts an FD_ACCEPT message immediately.

The FD_WRITE event is handled slightly differently. An FD_WRITE message is posted when a socket is first connected with connect/WSAConnect (after FD_CONNECT, if also registered) or accepted with accept/WSAAccept, and then after a send operation fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will be notified that sends are again possible with an FD_WRITE message.

The FD_OOB event is used only when a socket is configured to receive out-of-band data separately. (See section DECnet Out-Of-band data for a discussion of this topic.) If the socket is configured to receive out-of-band data in-line, the out-of-band (expedited) data is treated as normal data and the application should register an interest in, and will receive, FD_READ events, not FD_OOB events. An application can set or inspect the way in which out-of-band data is to be handled by using setsockopt or getsockopt for the SO_OOBINLINE option.

The error code in an FD_CLOSE message indicates whether the socket close was graceful or abortive. If the error code is zero, then the close was graceful; if the error code is WSAECONNRESET, then the socket's virtual circuit was reset. This only applies to connection-oriented sockets such as SOCK_STREAM.

The FD_CLOSE message is posted when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means that the FD_CLOSE is posted when the connection goes into the TIME WAIT or CLOSE WAIT states. This results from the remote end performing a shutdown on the send side or a closesocket. FD_CLOSE should only be posted after all data is read from a socket, but an application should check for remaining data upon receipt of FD_CLOSE to avoid any possibility of losing data.

Please note your application will receive ONLY an FD_CLOSE message to indicate closure of a virtual circuit, and only when all the received data has been read if this is a graceful close. It will not receive an FD_READ message to indicate this condition.

The FD_QOS or FD_GROUP_QOS message is posted when any field in the flow specification associated with socket s or the socket group that s belongs to has changed, respectively. Applications should use WSAIoctl with command SIO_GET_QOS or SIO_GET_GROUP_QOS to get the current QOS for socket s or for the socket group s belongs to, respectively.

The FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events are considered "edge triggered" as well. A message will be posted exactly once when a change occurs after the application has request the notification by issuing WSAIoctl with SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE correspondingly. Further messages will not be forthcoming until the application reissues the IOCTL AND another change is detected since the IOCTL has been issued.

Here is a summary of events and conditions for each asynchronous notification message:

  • FD_READ:
    1. when WSAAsyncSelect called, if there is data currently available to receive,
    2. when data arrives, if FD_READ not already posted,
    3. after recv or recvfrom called (with or without MSG_PEEK), if data is still available to receive.

      Note when setsockopt SO_OOBINLINE is enabled, "data" includes both normal data and out-of-band (OOB) data in the instances noted above.

  • FD_WRITE:
    1. when WSAAsyncSelect called, if a send or sendto is possible
    2. after connect or accept called, when connection established
    3. after send or sendto fail with WSAEWOULDBLOCK, when send or sendto are likely to succeed,
    4. after bind on a connectionless socket. FD_WRITE may or may not occur at this time (implementation-dependent). In any case, a connectionless socket is always writeable immediately after a bind operation.
  • FD_OOB: Only valid when setsockopt SO_OOBINLINE is disabled (default).
    1. when WSAAsyncSelect called, if there is OOB data currently available to receive with the MSG_OOB flag,
    2. when OOB data arrives, if FD_OOB not already posted,
    3. after recv or recvfrom called with or without MSG_OOB flag, if OOB data is still available to receive.
  • FD_ACCEPT:
    1. when WSAAsyncSelect called, if there is currently a connection request available to accept,
    2. when a connection request arrives, if FD_ACCEPT not already posted,
    3. after accept called, if there is another connection request available to accept.
  • FD_CONNECT:
    1. when WSAAsyncSelect called, if there is currently a connection established,
    2. after connect called, when connection is established (even when connect succeeds immediately, as is typical with a datagram socket),
    3. after calling WSAJoinLeaf, when join operation completes,
    4. after connect, WSAConnect, or WSAJoinLeaf was called with a nonblocking, connection-oriented socket. The initial operation returned with a specific error of WSAEWOULDBLOCK, but the network operation went ahead. Whether the operation eventually succeeds or not, when the outcome has been determined, FD_CONNECT happens. The client should check the error code to determine whether the outcome was successful or failed.
  • FD_CLOSE: Only valid on connection-oriented sockets (for example, SOCK_STREAM)
    1. when WSAAsyncSelect called, if socket connection has been closed,
    2. after remote system initiated graceful close, when no data currently available to receive (note: if data has been received and is waiting to be read when the remote system initiates a graceful close, the FD_CLOSE is not delivered until all pending data has been read),
    3. after local system initiates graceful close with shutdown and remote system has responded with "End of Data" notification (for example, TCP FIN), when no data currently available to receive,
    4. when remote system terminates connection (for example, sent TCP RST), and lParam will contain WSAECONNRESET error value.

      Note FD_CLOSE is not posted after closesocket is called.

  • FD_QOS:
    1. when WSAAsyncSelect called, if the quality of service associated with the socket has been changed,
    2. after WSAIoctl with SIO_GET_QOS called, when the quality of service is changed.
  • FD_GROUP_QOS (Reserved for future use with socket groups):
    1. when WSAAsyncSelect called, if the group quality of service associated with the socket has been changed,
    2. after WSAIoctl with SIO_GET_GROUP_QOS called, when the group quality of service is changed.
  • FD_ROUTING_INTERFACE_CHANGE:
    1. after WSAIoctl with SIO_ROUTING_INTERFACE_CHANGE called, when the local interface that should be used to reach the destination specified in the IOCTL changes.
  • FD_ADDRESS_LIST_CHANGE
    1. after WSAIoctl with SIO_ADDRESS_LIST_CHANGE called, when the list of local addresses to which the application can bind changes.

Return Values

If the WSAAsyncSelect function succeeds, the return value is zero provided the application's declaration of interest in the network event set was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that one of the specified parameters was invalid such as the window handle not referring to an existing window, or the specified socket is in an invalid state.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor is not a socket.

Additional error codes can be set when an application window receives a message. This error code is extracted from the lParam in the reply message using the WSAGETSELECTERROR macro. Possible error codes for each network event are:

Event: FD_CONNECT

Error Code | Meaning
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to connect was forcefully rejected.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAEFAULT | The namelen parameter is incorrect.
WSAEINVAL | The socket is already bound to an address.
WSAEISCONN | The socket is already connected.
WSAEMFILE | No more file descriptors are available.
WSAENOBUFS | No buffer space is available. The socket cannot be connected.
WSAENOTCONN | The socket is not connected.
WSAETIMEDOUT | Attempt to connect timed out without establishing a connection.

Event: FD_CLOSE

Error Code | Meaning
WSAENETDOWN | The network subsystem has failed.
WSAECONNRESET | The connection was reset by the remote side.
WSAECONNABORTED | The connection was terminated due to a time-out or other failure.

Event: FD_READ

Event: FD_WRITE

Event: FD_OOB

Event: FD_ACCEPT

Event: FD_QOS

Event: FD_GROUP_QOS

Event: FD_ADDRESS_LIST_CHANGE

Error Code | Meaning
WSAENETDOWN | The network subsystem has failed.

Event: FD_ROUTING_INTERFACE_CHANGE

Error Code | Meaning
WSAENETUNREACH | The specified destination is no longer reachable
WSAENETDOWN | The network subsystem has failed.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

select, WSAEventSelect


WSACancelAsyncRequest

The Windows Sockets WSACancelAsyncRequest function cancels an incomplete asynchronous operation.

int WSACancelAsyncRequest (
  HANDLE hAsyncTaskHandle
);

Parameters

hAsyncTaskHandle
[in] The handle that specifies the asynchronous operation to be canceled.

Remarks

The WSACancelAsyncRequest function is used to cancel an asynchronous operation that was initiated by one of the WSAAsyncGetXByY functions such as WSAAsyncGetHostByName. The operation to be canceled is identified by the hAsyncTaskHandle parameter, which should be set to the asynchronous task handle as returned by the initiating WSAAsyncGetXByY function.

An attempt to cancel an existing asynchronous WSAAsyncGetXByY operation can fail with an error code of WSAEALREADY for two reasons. First, the original operation has already completed and the application has dealt with the resultant message. Second, the original operation has already completed but the resultant message is still waiting in the application window queue.

Return Values

The value returned by WSACancelAsyncRequest is zero if the operation was successfully canceled. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that the specified asynchronous task handle was invalid
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEALREADY | The asynchronous routine being canceled has already completed.

Note It is unclear whether the application can usefully distinguish between WSAEINVAL and WSAEALREADY, since in both cases the error indicates that there is no asynchronous operation in progress with the indicated handle. [Trivial exception: zero is always an invalid asynchronous task handle.] The Windows Sockets specification does not prescribe how a conformant Windows Sockets provider should distinguish between the two cases. For maximum portability, a Windows Sockets application should treat the two errors as equivalent.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSAAsyncGetHostByAddr, WSAAsyncGetHostByName, WSAAsyncGetProtoByName, WSAAsyncGetProtoByNumber, WSAAsyncGetServByName, WSAAsyncGetServByPort


WSACancelBlockingCall

This function has been removed in compliance with the Windows Sockets 2 specification, revision 2.2.0.

The function is not exported directly by the WS2_32.DLL, and Windows Sockets 2 applications should not use this function. Windows Sockets 1.1 applications that call this function are still supported through the WINSOCK.DLL and WSOCK32.DLL.

Blocking hooks are generally used to keep a single-threaded GUI application responsive during calls to blocking functions. Instead of using blocking hooks, an applications should use a separate thread (separate from the main GUI thread) for network activity.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSACleanup

The Windows Sockets WSACleanup function terminates use of the WS2_32.DLL.

int  WSACleanup (void);

Remarks

An application or DLL is required to perform a successful WSAStartup call before it can use Windows Sockets services. When it has completed the use of Windows Sockets, the application or DLL must call WSACleanup to deregister itself from a Windows Sockets implementation and allow the implementation to free any resources allocated on behalf of the application or DLL. Any pending blocking or asynchronous calls issued by any thread in this process are canceled without posting any notification messages or without signaling any event objects. Any pending overlapped send and receive operations (WSASend/WSASendTo/WSARecv/WSARecvFrom with an overlapped socket) issued by any thread in this process are also canceled without setting the event object or invoking the completion routine, if specified. In this case, the pending overlapped operations fail with the error status WSA_OPERATION_ABORTED.

Sockets that were open when WSACleanup was called are reset and automatically deallocated as if closesocket were called; sockets that have been closed with closesocket but that still have pending data to be sent can be affected—the pending data can be lost if the WS2_32.DLL is unloaded from memory as the application exits. To insure that all pending data is sent, an application should use shutdown to close the connection, then wait until the close completes before calling closesocket and WSACleanup. All resources and internal state, such as queued un-posted messages, must be deallocated so as to be available to the next user.

There must be a call to WSACleanup for every successful call to WSAStartup made by a task. Only the final WSACleanup for that task does the actual cleanup; the preceding calls simply decrement an internal reference count in the WS2_32.DLL.

Return Values

The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Attempting to call WSACleanup from within a blocking hook and then failing to check the return code is a common programming error in Windows Socket 1.1 applications. If an application needs to quit while a blocking call is outstanding, the application must first cancel the blocking call with WSACancelBlockingCall then issue the WSACleanup call once control has been returned to the application.

In a multithreaded environment, WSACleanup terminates Windows Sockets operations for all threads.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

closesocket, shutdown, WSAStartup


WSACloseEvent

The Windows Sockets WSACloseEvent function closes an open event object handle.

BOOL WSACloseEvent(
  WSAEVENT hEvent
);

Parameters

hEvent
[in] An object handle identifying the open event.

Remarks

The handle to the event object is closed so that further references to this handle will fail with the error WSA_INVALID_HANDLE.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To get extended error information, call WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSA_INVALID_HANDLE | The hEvent is not a valid event object handle.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACreateEvent, WSAEnumNetworkEvents, WSAEventSelect, WSAGetOverlappedResult, WSARecv, WSARecvFrom, WSAResetEvent, WSASend, WSASendTo, WSASetEvent, WSAWaitForMultipleEvents


WSAConnect

The Windows Sockets WSAConnect function establishes a connection to another socket application, exchanges connect data, and specifies needed quality of service based on the supplied FLOWSPEC structure.

int  WSAConnect (
  SOCKET s,
  const struct sockaddr FAR * name,
  int namelen,
  LPWSABUF lpCallerData,
  LPWSABUF lpCalleeData,
  LPQOS lpSQOS,
  LPQOS lpGQOS
);

Parameters

s
[in] A descriptor identifying an unconnected socket.
name
[in] The name of the socket in the other application to which to connect.
namelen
[in] The length of the name.
lpCallerData
[in] A pointer to the user data that is to be transferred to the other socket during connection establishment.
lpCalleeData
[out] A pointer to the user data that is to be transferred back from the other socket during connection establishment.
lpSQOS
[in] A pointer to the FLOWSPEC structures for socket s, one for each direction.
lpGQOS
[in] Reserved for future use with socket groups. A pointer to the FLOWSPEC structures for the socket group (if applicable).

Remarks

The WSAConnect function is used to create a connection to the specified destination, and to perform a number of other ancillary operations that occur at connect time. If the socket, s, is unbound, unique values are assigned to the local association by the system, and the socket is marked as bound.

For connection-oriented sockets (for example, type SOCK_STREAM), an active connection is initiated to the foreign host using name (an address in the name space of the socket; for a detailed description, please see bind). When this call completes successfully, the socket is ready to send/receive data. If the address field of the name structure is all zeroes, WSAConnect will return the error WSAEADDRNOTAVAIL. Any attempt to reconnect an active connection will fail with the error code WSAEISCONN.

For connection-oriented, nonblocking sockets, it is often not possible to complete the connection immediately. In such cases, this function returns the error WSAEWOULDBLOCK. However, the operation proceeds. When the success or failure outcome becomes known, it may be reported in one of several ways depending on how the client registers for notification. If the client uses select, success is reported in the writefds set and failure is reported in the exceptfds set. If the client uses WSAAsyncSelect or WSAEventSelect, the notification is announced with FD_CONNECT and the error code associated with the FD_CONNECT indicates either success or a specific reason for failure.

For a connectionless socket (for example, type SOCK_DGRAM), the operation erformed by WSAConnect is merely to establish a default destination address so that the socket can be used on subsequent connection-oriented send and receive operations (send , WSASend, recv, and WSARecv). Any datagrams received from an address other than the destination address specified will be discarded. If the address field of the name structure is all zeroes, the socket will be disconnected. Then, the default remote address will be indeterminate, so send/WSASend and recv/WSARecv calls will return the error code WSAENOTCONN. However, sendto/WSASendTo and recvfrom/WSARecvFrom can still be used. The default destination can be changed by simply calling WSAConnect again, even if the socket is already "connected". Any datagrams queued for receipt are discarded if name is different from the previous WSAConnect.

For connectionless sockets, name can indicate any valid address, including a broadcast address. However, to connect to a broadcast address, a socket must have setsockopt SO_BROADCAST enabled. Otherwise, WSAConnect will fail with the error code WSAEACCES.

On connectionless sockets, exchange of user-to-user data is not possible and the corresponding parameters will be silently ignored.

The application is responsible for allocating any memory space pointed to directly or indirectly by any of the parameters it specifies.

The lpCallerData is a value parameter that contains any user data that is to be sent along with the connection request. If lpCallerData is NULL, no user data will be passed to the peer. The lpCalleeData is a result parameter that will contain any user data passed back from the other socket as part of the connection establishment in a WSABUF structure. The member lpCalleeData->len initially contains the length of the buffer allocated by the application and pointed to by lpCalleeData->buf. lpCalleeData->len will be set to zero if no user data has been passed back. The lpCalleeData information will be valid when the connection operation is complete. For blocking sockets, the connection operation completes when the WSAConnect function returns. For nonblocking sockets, completion will be after the FD_CONNECT notification has occurred. If lpCalleeData is NULL, no user data will be passed back. The exact format of the user data is specific to the address family to which the socket belongs.

At connect time, an application can use the lpSQOS and lpGQOS parameters to override any previous quality of service specification made for the socket through WSAIoctl with either the SIO_SET_QOS or SIO_SET_GROUP_QOS opcodes.

lpSQOS specifies the FLOWSPEC structures for socket s, one for each direction, followed by any additional provider-specific parameters. If either the associated transport provider in general or the specific type of socket in particular cannot honor the quality of service request, an error will be returned as indicated below. The sending or receiving flow specification values will be ignored, respectively, for any unidirectional sockets. If no provider-specific parameters are supplied, the buf and len fields of lpSQOS->ProviderSpecific should be set to NULL and zero, respectively. A NULL value for lpSQOS indicates no application supplied quaility of service.

Reserved for future use with socket groups, lpGQOS specifies the FLOWSPEC structures for the socket group (if applicable), one for each direction, followed by any additional provider-specific parameters. If no provider-specific parameters are supplied, the buf and len fields of lpGQOS->ProviderSpecific should be set to NULL and zero, respectively. A NULL value for lpGQOS indicates no application-supplied group quality of service. This parameter will be ignored if s is not the creator of the socket group.

When connected sockets become closed for whatever reason, they should be discarded and recreated. It is safest to assume that when things go awry for any reason on a connected socket, the application must discard and recreate the needed sockets in order to return to a stable point.

Return Values

If no error occurs, WSAConnect returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError. On a blocking socket, the return value indicates success or failure of the connection attempt.

With a nonblocking socket, the connection attempt can not be completed immediately. In this case, WSAConnect will return SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK. In this case, the application can:

  1. Use select to determine the completion of the connection request by checking if the socket is writeable.
  2. If your application is using WSAAsyncSelect to indicate interest in connection events, then your application will receive an FD_CONNECT notification when the connect operation is complete(successful or not).
  3. If your application is using WSAEventSelect to indicate interest in connection events, then the associated event object will be signaled when the connect operation is complete (successful or not).

For a nonblocking socket, until the connection attempt completes all subsequent calls to WSAConnect on the same socket will fail with the error code WSAEALREADY.

If the return error code indicates the connection attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the application can call WSAConnect again for the same socket.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | The local address of the socket is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs during the execution of bind, but could be delayed until this function if the bind function operates on a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be "committed" at the time of this function.
WSAEINTR | The (blocking) Windows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEALREADY | A nonblocking connect /WSAConnect call is in progress on the specified socket.
WSAEADDRNOTAVAIL | The remote address is not a valid address (such as ADDR_ANY).
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to connect was rejected.
WSAEFAULT | The name or the namelen parameter is not a valid part of the user address space, the namelen parameter is too small, the buffer length for lpCalleeData, lpSQOS, and lpGQOS are too small, or the buffer length for lpCallerData is too large.
WSAEINVAL | The parameter s is a listening socket, or the destination address specified is not consistent with that of the constrained group the socket belongs to.
WSAEISCONN | The socket is already connected (connection-oriented sockets only).
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAENOBUFS | No buffer space is available. The socket cannot be connected.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The FLOWSPEC structures specified in lpSQOS and lpGQOS cannot be satisfied.
WSAEPROTONOSUPPORT | The lpCallerData argument is not supported by the service provider.
WSAETIMEDOUT | Attempt to connect timed out without establishing a connection.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the connection cannot be completed immediately.
WSAEACCES | Attempt to connect datagram socket to broadcast address failed because setsockopt SO_BROADCAST is not enabled.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, bind, connect, getsockname, getsockopt, select, socket, WSAAsyncSelect, WSAEventSelect


WSACreateEvent

The Windows Sockets connect function creates a new event object.

WSAEVENT  WSACreateEvent(void);

Remarks

The WSACreateEvent function is used to create an event object created that is manual reset with an initial state of nonsignaled. Windows Sockets 2 event objects are system objects in Win32 environments. Therefore, if a Win32 application desires auto reset events, it can call the native WSACreateEvent Win32 function directly. The scope of an event object is limited to the process in which it is created.

Return Values

If no error occurs, WSACreateEvent returns the handle of the event object. Otherwise, the return value is WSA_INVALID_EVENT. To get extended error information, call WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to create the event object.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACloseEvent, WSAEnumNetworkEvents, WSAEventSelect, WSAGetOverlappedResult, WSARecv, WSARecvFrom, WSAResetEvent, WSASend, WSASendTo, WSASetEvent, WSAWaitForMultipleEvents


WSADuplicateSocket

The Windows Sockets WSADuplicateSocket function returns a WSAPROTOCOL_INFO structure that can be used to create a new socket descriptor for a shared socket.

int WSADuplicateSocket (
  SOCKET s,
  DWORD dwProcessId,
  LPWSAPROTOCOL_INFO lpProtocolInfo
);

Parameters

s
[in] A descriptor identifying the local socket.
dwProcessId
[in] The process ID of the target process in which the duplicated socket will be used.
lpProtocolInfo
[out] A pointer to a buffer allocated by the client that is large enough to contain a WSAPROTOCOL_INFO structure. The service provider copies the protocol info structure contents to this buffer.

Remarks

The WSADuplicateSocket function is used to enable socket sharing between processes. A source process calls WSADuplicateSocket to obtain a special WSAPROTOCOL_INFO structure. It uses some interprocess communications (IPC) mechanism to pass the contents of this structure to a target process, which in turn uses it in a call to WSASocket to obtain a descriptor for the duplicated socket. The special WSAPROTOCOL_INFO structure can only be used once by the target process.

Sockets can be shared among threads in a given process without using the WSADuplicateSocket function because a socket descriptor is valid in all threads of a process

One possible scenario for establishing and handing off a shared socket is illustrated below:

Source Process | IPC | Destination Process
1) WSASocket, WSAConnect |  |
2) Request target process ID | Þ |
 |  | 3) Receive process ID request and respond
4) Receive process ID | Ü |
5) Call WSADuplicateSocket to get a special WSAPROTOCOL_INFO structure |  |
6) Send WSAPROTOCOL_INFO structure to target |  |
 | Þ | 7) Receive WSAPROTOCOL_INFO structure
 |  | 8) Call WSASocket to create shared socket descriptor.
10) closesocket |  | 9)Use shared socket for data exchange

The descriptors that reference a shared socket can be used independently for I/O. However, the Windows Sockets interface does not implement any type of access control so it is up to the processes involved to coordinate their operations on a shared socket. Shared sockets are typically used to have one process that is responsible for creating sockets and establishing connections, and other processes that are responsible for information exchange.

All of the state information associated with a socket is held in common across all the descriptors because the socket descriptors are duplicated and not the actual socket. For example, a setsockopt operation performed using one descriptor is subsequently visible using a getsockopt from any or all descriptors. A process can call closesocket on a duplicated socket and the descriptor will become deallocated. The underlying socket, however, will remain open until closesocket is called by the last remaining descriptor.

Notification on shared sockets is subject to the usual constraints of WSAAsyncSelect and WSAEventSelect. Issuing either of these calls using any of the shared descriptors cancels any previous event registration for the socket, regardless of which descriptor was used to make that registration. Thus, for example, a shared socket cannot deliver FD_READ events to process A and FD_WRITE events to process B. For situations when such tight coordination is required, developers would be advised to use threads instead of separate processes.

Return Values

If no error occurs, WSADuplicateSocket returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that one of the specified parameters was invalid.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEMFILE | No more socket descriptors are available.
WSAENOBUFS | No buffer space is available. The socket cannot be created.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpProtocolInfo argument is not a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSASocket


WSAEnumNameSpaceProviders

The Windows Sockets WSAEnumNameSpaceProviders function retrieves information about available name spaces.

INT WSAAPI WSAEnumNameSpaceProviders (
  IN OUT LPDWORD lpdwBufferLength,
  OUT LPWSANAMESPACE_INFO lpnspBuffer
);

Parameters

lpdwBufferLength
[in/out] On input, the number of bytes contained in the buffer pointed to by lpnspBuffer. On output (if the function fails, and the error is WSAEFAULT), the minimum number of bytes to pass for the lpnspBuffer to retrieve all the requested information. The passed-in buffer must be sufficient to hold all of the name space information.
lpnspBuffer
[out] A buffer that is filled with WSANAMESPACE_INFO structures. The returned structures are located consecutively at the head of the buffer. Variable sized information referenced by pointers in the structures point to locations within the buffer located between the end of the fixed sized structures and the end of the buffer. The number of structures filled in is the return value of WSAEnumNameSpaceProviders.

Return Values

The WSAEnumNameSpaceProviders function returns the number of WSANAMESPACE_INFO structures copied into lpnspBuffer. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSAEFAULT | the buffer length was too small to receive all the relevant WSANAMESPACE_INFO structures and associated information. Pass in a buffer at least as large as the value returned in lpdwBufferLength.
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSAEnumNetworkEvents

The Windows Sockets WSAEnumNetworkEvents function discovers occurrences of network events for the indicated socket, clear internal network event records, and reset event objects (optional).

int WSAEnumNetworkEvents (
  SOCKET s,
  WSAEVENT hEventObject,
  LPWSANETWORKEVENTS lpNetworkEvents
);

Parameters

s
[in] A descriptor identifying the socket.
hEventObject
[in] An optional handle identifying an associated event object to be reset.
lpNetworkEvents
[out] A pointer to a WSANETWORKEVENTS structure that is filled with a record of network events that occurred and any associated error codes.

Remarks

The WSAEnumNetworkEvents function is used to discover which network events have occurred for the indicated socket since the last invocation of this function. It is intended for use in conjunction with WSAEventSelect, which associates an event object with one or more network events. The recording of network events commences when WSAEventSelect is called with a nonzero lNetworkEvents parameter and remains in effect until another call is made to WSAEventSelect with the lNetworkEvents parameter set to zero, or until a call is made to WSAAsyncSelect.

WSAEnumNetworkEvents only reports network activity and errors nominated through WSAEventSelect. See the descriptions of select and WSAAsyncSelect to find out how those functions report network activity and errors.

The socket's internal record of network events is copied to the structure referenced by lpNetworkEvents, whereafter the internal network events record is cleared. If the hEventObject parameter is not null, the indicated event object is also reset. The Windows Sockets provider guarantees that the operations of copying the network event record, clearing it and resetting any associated event object are automatic, such that the next occurrence of a nominated network event will cause the event object to become set. In the case of this function returning SOCKET_ERROR, the associated event object is not reset and the record of network events is not cleared.

The lNetworkEvents member of the WSANETWORKEVENTS structure indicates which of the FD_XXX network events have occurred. The iErrorCode array is used to contain any associated error codes with the array index corresponding to the position of event bits in lNetworkEvents. Identifiers such as FD_READ_BIT and FD_WRITE_BIT can be used to index the iErrorCode array. Note that only those elements of the iErrorCode array are set that correspond to the bits set in lNetworkEvents field. Other fields are not modified (this is important for backwards compatibility with the applications that are not aware of new FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events).

The following error codes can be returned along with the corresponding network event:

Event: FD_CONNECT

Error Code | Meaning
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to connect was forcefully rejected.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAENOBUFS | No buffer space is available. The socket cannot be connected.
WSAETIMEDOUT | Attempt to connect timed out without establishing a connection

Event: FD_CLOSE

Error Code | Meaning
WSAENETDOWN | The network subsystem has failed.
WSAECONNRESET | The connection was reset by the remote side.
WSAECONNABORTED | The connection was terminated due to a time-out or other failure.

Event: FD_READ

Event: FD_WRITE

Event: FD_OOB

Event: FD_ACCEPT

Event: FD_QOS

Event: FD_GROUP_QOS

Event: FD_ADDRESS_LIST_CHANGE

Error Code | Meaning
WSAENETDOWN | The network subsystem has failed.

Event: FD_ROUTING_INTERFACE_CHANGE

Error Code | Meaning
WSAENETUNREACH | The specified destination is no longer reachable
WSAENETDOWN | The network subsystem has failed.

Return Values

The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that one of the specified parameters was invalid.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpNetworkEvents argument is not a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSAEventSelect


WSAEnumProtocols

The Windows Sockets WSAEnumProtocols function retrieves information about available transport protocols.

int WSAEnumProtocols (
  LPINT lpiProtocols,
  LPWSAPROTOCOL_INFO lpProtocolBuffer,
  ILPDWORD lpdwBufferLength
);

Parameters

lpiProtocols
[in] A NULL-terminated array of iProtocol values. This parameter is optional; if lpiProtocols is NULL, information on all available protocols is returned. Otherwise, information is retrieved only for those protocols listed in the array.
lpProtocolBuffer
[out] A buffer that is filled with WSAPROTOCOL_INFO structures.
lpdwBufferLength
[in/out] On input, the count of bytes in the lpProtocolBuffer buffer passed to WSAEnumProtocols. On output, the minimum buffer size that can be passed to WSAEnumProtocols to retrieve all the requested information. This routine has no ability to enumerate over multiple calls; the passed-in buffer must be large enough to hold all entries in order for the routine to succeed. This reduces the complexity of the API and should not pose a problem because the number of protocols loaded on a machine is typically small.

Remarks

The WSAEnumProtocols function is used to discover information about the collection of transport protocols and protocol chains installed on the local machine. Since layered protocols are only usable by applications when installed in protocol chains, information on layered protocols is not included in lpProtocolBuffer. The lpiProtocols parameter can be used as a filter to constrain the amount of information provided. Often, lpiProtocols will be supplied as a NULL pointer that will cause the function to return information on all available transport protocols and protocol chains.

A WSAPROTOCOL_INFO structure is provided in the buffer pointed to by lpProtocolBuffer for each requested protocol. If the supplied buffer is not large enough (as indicated by the input value of lpdwBufferLength ), the value pointed to by lpdwBufferLength will be updated to indicate the required buffer size. The application should then obtain a large enough buffer and call this WSAEnumProtocols again.

The order in which the WSAPROTOCOL_INFO structures appear in the buffer coincides with the order in which the protocol entries were registered by the service provider using the WS2_32.DLL, or with any subsequent re-ordering that can have occurred through the Windows Sockets applet or DLL supplied for establishing default TCP/IP providers.

Return Values

If no error occurs, WSAEnumProtocols returns the number of protocols to be reported. Otherwise, a value of SOCKET_ERROR is returned and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress.
WSAEINVAL | Indicates that one of the specified parameters was invalid.
WSAENOBUFS | The buffer length was too small to receive all the relevant WSAPROTOCOL_INFO structures and associated information. Pass in a buffer at least as large as the value returned in lpdwBufferLength.
WSAEFAULT | One or more of the lpiProtocols, lpProtocolBuffer, or lpdwBufferLength arguments are not a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSAEventSelect

The Windows Sockets WSAEventSelect function specifies an event object to be associated with the supplied set of FD_XXX network events.

int WSAEventSelect (
  SOCKET s,
  WSAEVENT hEventObject,
  long lNetworkEvents
);

Parameters

s
[in] A descriptor identifying the socket.
hEventObject
[in] A handle identifying the event object to be associated with the supplied set of FD_XXX network events.
lNetworkEvents
[in] A bitmask that specifies the combination of FD_XXX network events in which the application has interest.

Remarks

The WSAEventSelect function is used to specify an event object, hEventObject, to be associated with the selected FD_XXX network events, lNetworkEvents. The socket for which an event object is specified is identified by the s parameter. The event object is set when any of the nominated network events occur.

The WSAEventSelect function operates very similarly to WSAAsyncSelect, the difference being in the actions taken when a nominated network event occurs. The WSAAsyncSelect function causes an application-specified Windows message to be posted. The WSAEventSelect sets the associated event object and records the occurrence of this event in an internal network event record. An application can use WSAWaitForMultipleEvents to wait or poll on the event object, and use WSAEnumNetworkEvents to retrieve the contents of the internal network event record and thus determine which of the nominated network events have occurred.

WSAEventSelect is the only function that causes network activity and errors to be recorded and retrievable through WSAEnumNetworkEvents. See the descriptions of select and WSAAsyncSelect to find out how those functions report network activity and errors.

The WSAEventSelect function automatically sets socket s to nonblocking mode, regardless of the value of lNetworkEvents. See ioctlsocket /WSAIoctl about how to set the socket back to blocking mode.

The lNetworkEvents parameter is constructed by or'ing any of the values specified in the following list.

Value | Meaning
FD_READ | Want to receive notification of readiness for reading
FD_WRITE | Want to receive notification of readiness for writing
FD_OOB | Want to receive notification of the arrival of out-of-band data
FD_ACCEPT | Want to receive notification of incoming connections
FD_CONNECT | Want to receive notification of completed connection or multipoint "join" operation
FD_CLOSE | Want to receive notification of socket closure
FD_QOS | Want to receive notification of socket Quality of Service (QOS) changes
FD_GROUP_QOS | Reserved for future use with socket groups. Want to receive notification of socket group Quality of Service (QOS) changes
FD_ROUTING _INTERFACE_CHANGE | Want to receive notification of routing interface changes for the specified destination
FD_ADDRESS_LIST _CHANGE | Want to receive notification of local address list changes for the address family of the socket

Issuing a WSAEventSelect for a socket cancels any previous WSAAsyncSelect or WSAEventSelect for the same socket and clears the internal network event record. For example, to associate an event object with both reading and writing network events, the application must call WSAEventSelect with both FD_READ and FD_WRITE, as follows:

rc = WSAEventSelect(s, hEventObject, FD_READ|FD_WRITE);

It is not possible to specify different event objects for different network events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE network event will be associated with hEventObject2:

rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad

To cancel the association and selection of network events on a socket, lNetworkEvents should be set to zero, in which case the hEventObject parameter will be ignored.

rc = WSAEventSelect(s, hEventObject, 0);

Closing a socket with closesocket also cancels the association and selection of network events specified in WSAEventSelect for the socket. The application, however, still must call WSACloseEvent to explicitly close the event object and free any resources.

The socket created when the accept function is called has the same properties as the listening socket used to accept it. Any WSAEventSelect association and network events selection set for the listening socket apply to the accepted socket. For example, if a listening socket has WSAEventSelect association of hEventOject with FD_ACCEPT, FD_READ, and FD_WRITE, then any socket accepted on that listening socket will also have FD_ACCEPT, FD_READ, and FD_WRITE network events associated with the same hEventObject. If a different hEventObject or network events are desired, the application should call WSAEventSelect, passing the accepted socket and the desired new information.

Return Values

The return value is zero if the application's specification of the network events and the associated event object was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

As in the case of the select and WSAAsyncSelect functions, WSAEventSelect will frequently be used to determine when a data transfer operation (send or recv) can be issued with the expectation of immediate success. Nevertheless, a robust application must be prepared for the possibility that the event object is set and it issues a Windows Sockets call that returns WSAEWOULDBLOCK immediately. For example, the following sequence of operations is possible:

  1. Data arrives on socket s; Windows Sockets sets the WSAEventSelect event object.
  2. The application does some other processing.
  3. While processing, application issues an ioctlsocket(s, FIONREAD...) and notices that there is data ready to be read.
  4. The application issues a recv(s,...) to read the data.
  5. The application eventually waits on event object specified in WSAEventSelect, which returns immediately indicating that data is ready to read.
  6. The application issues recv(s,...), which fails with the error WSAEWOULDBLOCK.

Having successfully recorded the occurrence of the network event (by setting the corresponding bit in the internal network event record) and signaled the associated event object, no further actions are taken for that network event until the application makes the function call that implicitly re-enables the setting of that network event and signaling of the associated event object.

Network Event | Re-enabling function
FD_READ | recv, recvfrom, WSARecv, or WSARecvFrom
FD_WRITE | send, sendto, WSASend, or WSASendTo
FD_OOB | recv, recvfrom, WSARecv, or WSARecvFrom
FD_ACCEPT | accept or WSAAccept unless the error code returned is WSATRY_AGAIN indicating that the condition function returned CF_DEFER
FD_CONNECT | NONE
FD_CLOSE | NONE
FD_QOS | WSAIoctl with command SIO_GET_QOS
FD_GROUP_QOS | Reserved for future use with socket groups. WSAIoctl with command SIO_GET_GROUP_QOS
FD_ROUTING _INTERFACE_CHANGE | WSAIoctl with command SIO_ROUTING_INTERFACE_CHANGE
FD_ADDRESS_LIST _CHANGE | WSAIoctl with command SIO_ADDRESS_LIST_CHANGE

Any call to the re-enabling routine, even one that fails, results in re-enabling of recording and signaling for the relevant network event and event object.

For FD_READ, FD_OOB, and FD_ACCEPT network events, network event recording and event object signaling are "level-triggered." This means that if the re-enabling routine is called and the relevant network condition is still valid after the call, the network event is recorded and the associated event object is set. This allows an application to be event-driven and not be concerned with the amount of data that arrives at any one time. Consider the following sequence:

  1. Transport provider receives 100 bytes of data on socket s and causes WS2_32.DLL to record the FD_READ network event and set the associated event object.
  2. The application issues recv( s, buffptr, 50, 0) to read 50 bytes.
  3. The transport provider causes WS2_32.DLL to record the FD_READ network event and sets the associated event object again since there is still data to be read.

With these semantics, an application need not read all available data in response to an FD_READ network event—a single recv in response to each FD_READ network event is appropriate.

The FD_QOS and FD_GROUP_QOS events are considered edge triggered. A message will be posted exactly once when a quality of service change occurs. Further messages will not be forthcoming until either the provider detects a further change in quality of service or the application renegotiates the quality of service for the socket.

The FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events are considered "edge triggered" as well. A message will be posted exactly once when a change occurs AFTER the application has request the notification by issuing WSAIoctl with SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE correspondingly. Further messages will not be forthcoming until the application reissues the IOCTL AND another change is detected since the IOCTL has been issued.

If a network event has already happened when the application calls WSAEventSelect or when the re-enabling function is called, then a network event is recorded and the associated event object is set as appropriate. For example, consider the following sequence:

  1. an application calls listen,
  2. a connect request is received but not yet accepted,
  3. the application calls WSAEventSelect specifying that it is interested in the FD_ACCEPT network event for the socket. Due to the persistence of network events, Windows Sockets records the FD_ACCEPT network event and sets the associated event object immediately.

The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept, and then after a send fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will find out that sends are again possible when an FD_WRITE network event is recorded and the associated event object is set.

The FD_OOB network event is used only when a socket is configured to receive out-of-band data separately. If the socket is configured to receive out-of-band data in-line, the out-of-band (expedited) data is treated as normal data and the application should register an interest in, and will get, FD_READ network event, not FD_OOB network event. An application can set or inspect the way in which out-of-band data is to be handled by using setsockopt or getsockopt for the SO_OOBINLINE option.

The error code in an FD_CLOSE network event indicates whether the socket close was graceful or abortive. If the error code is zero, then the close was graceful; if the error code is WSAECONNRESET, then the socket's virtual circuit was reset. This only applies to connection-oriented sockets such as SOCK_STREAM.

The FD_CLOSE network event is recorded when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means that the FD_CLOSE is recorded when the connection goes into the TIME WAIT or CLOSE WAIT states. This results from the remote end performing a shutdown on the send side or a closesocket. FD_CLOSE should only be posted after all data is read from a socket, but an application should check for remaining data upon receipt of FD_CLOSE to avoid any possibility of losing data.

Please note Windows Sockets will record ONLY an FD_CLOSE network event to indicate closure of a virtual circuit. It will not record an FD_READ network event to indicate this condition.

The FD_QOS or FD_GROUP_QOS network event is recorded when any field in the flow specification associated with socket s or the socket group that s belongs to has changed, respectively. Applications should use WSAIoctl with command SIO_GET_QOS or SIO_GET_GROUP_QOS to get the current QOS for socket s or for the socket group s belongs to, respectively.

The FD_ROUTING_INTERFACE_CHANGE nework event is recorded when the local interface that should be used to reach the destination specified in WSAIoctl with SIO_ROUTING_INTERFACE_CHANGE changes after such IOCTL has been issued.

The FD_ADDRESS_LIST_CHANGE network event is recorded when the list of addresses of protocol family for the socket to which the application can bind changes after WSAIoctl with SIO_ADDRESS_LIST_CHANGE has been issued.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that one of the specified parameters was invalid, or the specified socket is in an invalid state.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSAAsyncSelect, WSACloseEvent, WSACreateEvent, WSAEnumNetworkEvents, WSAWaitForMultipleEvents


WSAGetLastError

The Windows Sockets WSAGetLastError function gets the error status for the last operation that failed.

int  WSAGetLastError (void);

Remarks

The WSAGetLastError function returns the last network error that occurred. When a particular Windows Sockets function indicates that an error has occurred, this function should be called to retrieve the appropriate error code. This error code can be different from the error code obtained from getsockopt SO_ERROR, which is socket-specific since WSAGetLastError is for all thread-specific sockets.

A successful function call, or a call to WSAGetLastError, does not reset the error code. To reset the error code, use the WSASetLastError function call with iError set to zero. A getsockopt SO_ERROR also resets the error code to zero.

The WSAGetLastError function should not be used to check for an error value on receipt of an asynchronous message. In this case, the error value is passed in the lParam field of the message, and this can differ from the value returned by WSAGetLastError.

Return Values

The return value indicates the error code for this thread's last Windows Sockets operation that failed.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getsockopt, WSASetLastError


WSAGetOverlappedResult

The Windows Sockets WSAGetOverlappedResult function returns the results of an overlapped operation on the specified socket.

BOOL WSAGetOverlappedResult (
  SOCKET s,
  LPWSAOVERLAPPED lpOverlapped,
  LPDWORD lpcbTransfer,
  BOOL fWait,
  LPDWORD lpdwFlags
);

Parameters

s
[in] A descriptor identifying the socket. This is the same socket that was specified when the overlapped operation was started by a call to WSARecv, WSARecvFrom, WSASend, WSASendTo, or WSAIoctl.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure that was specified when the overlapped operation was started.
pcbTransfer
[out] A pointer to a 32-bit variable that receives the number of bytes that were actually transferred by a send or receive operation, or by WSAIoctl.
fWait
[in] A flag that specifies whether the function should wait for the pending overlapped operation to complete. If TRUE, the function does not return until the operation has been completed. If FALSE and the operation is still pending, the function returns FALSE and the WSAGetLastError function returns WSA_IO_INCOMPLETE. The fWait parameter may be set to TRUE only if the overlapped operation selected the event-based completion notification.
lpdwFlags
[out] A pointer to a 32-bit variable that will receive one or more flags that supplement the completion status. If the overlapped operation was initiated through WSARecv or WSARecvFrom, this parameter will contain the results value for lpFlags parameter.

Remarks

The WSAGetOverlappedResult function reports results of last overlapped operation for the specified socket. The WSAOverlappedResult function is passed the socket descriptor and the WSAOVERLAPPED structure that were specified when the overlapped function was called. A pending operation is indicated when the function that started the operation returns FALSE and the WSAGetLastError function returns WSA_IO_PENDING. When an I/O operation such as WSARecv is pending, the function that started the operation resets the hEvent member of the WSAOVERLAPPED structure to the nonsignaled state. Then when the pending operation has completed, the system sets the event object to the signaled state.

If the fWait parameter is TRUE, WSAGetOverlappedResult determines whether the pending operation has been completed by waiting for the event object to be in the signaled state.A client may set fWait parameter to TRUE only if it selected event-based completion notification when the IO operation was requested. If another form of notification was selected, the usage of the hEvent parameter of the WSAOVERLAPPED structure is different, and setting fWait to TRUE causes unpredictable results.

Return Values

If WSAGetOverlappedResult succeeds, the return value is TRUE. This means that the overlapped operation has completed successfully and that the value pointed to by lpcbTransfer has been updated. If WSAGetOverlappedResult returns FALSE, this means that either the overlapped operation has not completed, the overlapped operation completed but with errors, or the overlapped operation's completion status could not be determined due to errors in one or more parameters to WSAGetOverlappedResult. On failure, the value pointed to by lpcbTransfer will not be updated. Use WSAGetLastError to determine the cause of the failure (either of WSAGetOverlappedResult or of the associated overlapped operation).

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSA_INVALID_HANDLE | The hEvent field of the WSAOVERLAPPED structure does not contain a valid event object handle.
WSA_INVALID_PARAMETER | One of the parameters is unacceptable.
WSA_IO_INCOMPLETE | The fWait parameter is FALSE and the I/O operation has not yet completed.
WSAEFAULT | One or more of the lpOverlapped, lpcbTransfer, or lpdwFlags arguments are not a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSAAccept, WSAConnect, WSACreateEvent, WSAIoctl, WSARecv, WSARecvFrom, WSASend, WSASendTo, WSAWaitForMultipleEvents


WSAGetQOSByName

The Windows Sockets WSAGetQOSByName function initializes a QUALITYOFSERVICE structure based on a named template, or it supplies a buffer to retrieve an enumeration of the available template names.

BOOL WSAGetQOSByName(
  SOCKET s,
  LPWSABUF lpQOSName,
  LPQOS lpQOS
);

Parameters

s
[in] A descriptor identifying a socket.
lpQOSName
[in out] A pointer to a specific quality of service template.
lpQOS
[out] A pointer to the QUALITYOFSERVICE structure to be filled.

Remarks

The WSAGetQOSByName function is used by applications to initialize a QUALITYOFSERVICE structure to a set of known values appropriate for a particular service class or media type. These values are stored in a template that is referenced by a well-known name. The client may retrieve these values by setting the buf parameter of the WSABUF indicated by lpQOSName, which points to a string of non-zero length specifying a template name. In this case, the usage of lpQOSName is IN only, and results are returned through lpQOS.

Alternatively, the client may use this function to retrieve an enumeration of available template names. The client may do this by setting the buf parameter of the WSABUF indicated by lpQOSName to a zero-length null-terminated string. In this case the buffer indicated by buf is over-written with a sequence of as many null-terminated template names that are available up to the number of bytes available in buf as indicated by the len parameter of the WSABUF indicated by lpQOSName. The list of names itself is terminated by a zero-length name. When the WSAGetQOSByName function is used to retrieve template names, the lpQOS parameter is ignored.

Return Values

If WSAGetQOSByName succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpQOSName or lpQOS parameter are not a valid part of the user address space, or the buffer length for lpQOS is too small.
WSAENVAL | The specified quality of service template name is invalid.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getsockopt, WSAAccept, WSAConnect


WSAGetServiceClassInfo

The Windows Sockets WSAGetServiceClassInfo function retrieves all of the class information (schema) pertaining to a specified service class from a specified name space provider.

INT WSAGetServiceClassInfo(
  LPGUID lpProviderId,
  LPGUID lpServiceClassId,
  LPDWORD lpdwBufferLength,
  LPWSASERVICECLASSINFO lpServiceClassInfo
);

Parameters

lpProviderId
[in] A pointer to a GUID that identifies a specific name space provider
lpServiceClassId
[in] A pointer to a GUID identifying the service class in question
lpdwBufferLength
[in/out] On input, the number of bytes contained in the buffer pointed to by lpServiceClassInfos. On output, if the function fails and the error is WSAEFAULT, then it contains the minimum number of bytes to pass for the lpServiceClassInfo to retrieve the record.
lpServiceClasslnfo
[out] A pointer to the service class information from the indicated name space provider for the specified service class.

Remarks

The WSAGetServiceClassInfo function retrieves service class information but the service class information retrieved from a particular name space provider might not be the complete set of class information that was supplied when the service class was installed. Individual name space providers are only required to retain service class information that is applicable to the name spaces that they support. See section Service Class Data Structures for more information.

Return Values

The return value is zero if the WSAGetServiceClassInfo was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSAEACCESS | The calling routine does not have sufficient privileges to access the information.
WSAEFAULT | The buffer referenced by lpServiceClassInfo is too small. Pass in a larger buffer.
WSAEINVAL | the specified service class ID or name space provider ID is invalid.
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
WSATYPE NOT FOUND | The specified class was not found.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSAGetServiceClassNameByClassId

WSAGetServiceClassNameByClassId The Windows Sockets WSAGetServiceClassNameByClassId function returns the name of the service associated with the given type. This name is the generic service name, like FTP or SNA, and not the name of a specific instance of that service.

INT WSAGetServiceClassNameByClassId(
  LPGUID lpServiceClassId,
  LPTSTR lpszServiceClassName,
  LPDWORD lpdwBufferLength
);

Parameters

lpServiceClassId
[in] A pointer to the GUID for the service class.
lpszServiceClassName
[out] A pointer to the service name.
lpdwBufferLength
[in/out] On input, the length of the buffer returned by lpszServiceClassName. On output, the length of the service name copied into lpszServiceClassName.

Return Values

The WSAGetServiceClassNameByClassId function returns a value of zero if successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSAEFAULT | The specified buffer referenced by lpszServiceClassName is too small. Pass in a larger buffer.
WSA_INVALID_PARAMETER | The lpServiceClassId parameter specified is invalid.
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSAHtonl

The Windows Sockets WSAHtonl function converts a u_long from host byte order to network byte order.

int WSAHtonl (
  SOCKET s,
  u_long hostlong,
  u_long FAR * lpnetlong
);

Parameters

s
[in] A descriptor identifying a socket.
hostlong
[in] A 32-bit number in host byte order.
lpnetlong
[out] A pointer to a 32-bit number in network byte order.

Remarks

The WSAHtonl function takes a 32-bit number in host byte order and returns a 32-bit number pointed to by the lpnetlong parameter in the network byte order associated with socket s.

Return Values

If no error occurs, WSAHtonl returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpnetlong parameter is not completely contained in a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

htonl, htons, ntohl, ntohs, WSANtohl, WSAHtons, WSANtohs


WSAHtons

The Windows Sockets WSAHtons function converts a u_short from host byte order to network byte order.

int WSAHtons (
  SOCKET s,
  u_short hostshort,
  u_short FAR * lpnetshort
);

Parameters

s
[in] A descriptor identifying a socket.
hostshort
[in] A 16-bit number in host byte order.
lpnetshort
[out] A pointer to a 16-bit number in network byte order.

Remarks

The WSAHtons function takes a 16-bit number in host byte order and returns a 16-bit number pointed to by the lpnetshort parameter in the network byte order associated with socket s.

Return Values

If no error occurs, WSAHtons returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpnetshort parameter is not completely contained in a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

htonl, htons, ntohl, ntohs, WSAHtonl, WSANtohl, WSANtohs


WSAInstallServiceClass

The Windows Sockets WSAInstallServiceClass function registers a service class schema within a name space. This schema includes the class name, class ID, and any name-space-specific information that is common to all instances of the service, such as the SAP ID or object ID.

INT WSAInstallServiceClass(
  LPWSASERVICECLASSINFO lpServiceClassInfo
);

Parameters

lpServiceClasslnfo
[in] The service class to name-space-specific type-mapping information. Multiple mappings can be handled at one time.

See section Service Class Data Structures for a description of pertinent data structures.

Return Values

The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSAEACCES | The calling function does not have sufficient privileges to install the Service.
WSAEALREADY | Service class information has already been registered for this service class ID. To modify service class info, first use WSARemoveServiceClass, and then re-install with updated class info data.
WSAEINVAL | The service class information was invalid or improperly structured.
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSAIoctl

The Windows Sockets WSAIoctl function controls the mode of a socket.

int WSAIoctl (
  SOCKET s,
  DWORD dwIoControlCode,
  LPVOID lpvInBuffer,
  DWORD cbInBuffer,
  LPVOID lpvOUTBuffer,
  DWORD cbOUTBuffer,
  LPDWORD lpcbBytesReturned,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE
);

Parameters

s
[in] A descriptor identifying a socket.
dwIoControlCode
[in] The control code of operation to perform.
lpvInBuffer
[in] A pointer to the input buffer.
cbInBuffer
[in] A number indicating the size of the input buffer.
lpvOutBuffer
[out] A pointer to the output buffer.
cbOutBuffer
[in] A number indicating the size of the output buffer.
lpcbBytesReturned
[out] A pointer to actual number of bytes of output.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for non-overlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the operation has been completed (ignored for non-overlapped sockets).

Remarks

The WSAIoctl function is used to set or retrieve operating parameters associated with the socket, the transport protocol, or the communications subsystem.

If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a non-overlapped socket. For a non-overlapped socket, lpOverlapped and lpCompletionRoutine parameters are ignored, which cause the function to behave like the standard ioctlsocket function except that WSAIoctl can block if socket s is in the blocking mode. If socket s is in the nonblocking mode, this function can return WSAEWOULDBLOCK when the specified operation cannot be finished immediately. In this case, the application may change the socket to the blocking mode and reissue the request or wait for the corresponding network event (such as FD_ROUTING_INTERFACE_CHANGE or FD_ADDRESS_LIST_CHANGE in case of SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE) using Windows message (using WSAAsyncSelect) or event (using WSAEventSelect) based notification mechanism

For overlapped sockets, operations that cannot be completed immediately will be initiated, and completion will be indicated at a later time. The final completion status is retrieved through WSAGetOverlappedResult. The lpcbBytesReturned parameter is ignored.

Any ioctl may block indefinitely, depending on the service provider's implementation. If the application cannot tolerate blocking in a WSAIoctl call, overlapped I/O would be advised for ioctls that are especially likely to block including:

SIO_FINDROUTE
SIO_FLUSH
SIO_GET_QOS
SIO_GET_GROUP_QOS
SIO_SET_QOS
SIO_SET_GROUP_QOS
SIO_ROUTING_INTERFACE_CHANGE
SIO_ADDRESS_LIST_CHANGE

Some protocol-specific ioctls may also be especially likely to block. Check the relevant protocol-specific annex for any available information.

It is possible to adopt an encoding scheme that preserves the currently defined ioctlsocket opcodes while providing a convenient way to partition the opcode identifier space in as much as the dwIoControlCode parameter is now a 32-bit entity. The dwIoControlCode parameter is architected to allow for protocol and vendor independence when adding new control codes while retaining backward compatibility with the Windows Sockets 1.1 and Unix control codes. The dwIoControlCode parameter has the following form:

3 | 3 | 2 | 2 2 | 2 2 2 2 2 2 2 1 1 1 1 | 1 1 1 1 1 1
1 | 0 | 9 | 8 7 | 6 5 4 3 2 1 0 9 8 7 6 | 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
I | O | V | T | Vendor/Address Family | Code

I is set if the input buffer is valid for the code, as with IOC_IN.

O is set if the output buffer is valid for the code, as with IOC_OUT. Codes with both input and output parameters set both I and O.

V is set if there are no parameters for the code, as with IOC_VOID.

T is a two-bit quantity that defines the type of ioctl. The following values are defined:

0 – The ioctl is a standard Unix ioctl code, as with FIONREAD and FIONBIO.

1 – The ioctl is a generic Windows Sockets 2 ioctl code. New ioctl codes defined for Windows Sockets 2 will have T == 1.

2 – The ioctl applies only to a specific address family.

3 – The ioctl applies only to a specific vendor's provider. This type allows companies to be assigned a vendor number that appears in the Vendor/Address family field. Then, the vendor can define new ioctls specific to that vendor without having to register the ioctl with a clearinghouse, thereby providing vendor flexibility and privacy.

Vendor/Address family – An 11-bit quantity that defines the vendor who owns the code (if T == 3) or that contains the address family to which the code applies (if T == 2). If this is a Unix ioctl code (T == 0) then this field has the same value as the code on Unix. If this is a generic Windows Sockets 2 ioctl (T == 1) then this field can be used as an extension of the "code" field to provide additional code values.

Code – The 16-bit quantity that contains the specific ioctl code for the operation.

The following Unix ioctl codes (commands) are supported:

FIONBIO
Enable or disable nonblocking mode on socket s. lpvInBuffer points at an unsigned long, which is nonzero if nonblocking mode is to be enabled and zero if it is to be disabled. When a socket is created, it operates in blocking mode (that is, nonblocking mode is disabled). This is consistent with BSD sockets.

The WSAAsyncSelect or WSAEventSelect routine automatically sets a socket to nonblocking mode. If WSAAsyncSelect or WSAEventSelect has been issued on a socket, then any attempt to use WSAIoctl to set the socket back to blocking mode will fail with WSAEINVAL. To set the socket back to blocking mode, an application must first disable WSAAsyncSelect by calling WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect by calling WSAEventSelect with the lNetworkEvents parameter equal to zero.

FIONREAD
Determine the amount of data that can be read atomically from socket s. lpvOutBuffer points at an unsigned long in which WSAIoctl stores the result. If s is stream oriented (for example, type SOCK_STREAM), FIONREAD returns the total amount of data that can be read in a single receive operation; this is normally the same as the total amount of data queued on the socket (since data stream is byte-oriented, this is not guaranteed). If s is message oriented (for example, type SOCK_DGRAM), FIONREAD returns the size of the first datagram (message) queued on the socket.
SIOCATMARK
Determine whether or not all out-of-band data has been read. This applies only to a socket of stream-style (for example, type SOCK_STREAM) that has been configured for in-line reception of any out-of-band data (SO_OOBINLINE). If no out-of-band data is waiting to be read, the operation returns TRUE. Otherwise, it returns FALSE, and the next receive operation performed on the socket will retrieve some or all of the data preceding the "mark"; the application should use the SIOCATMARK operation to determine whether any remains. If there is any normal data preceding the "urgent" (out of band) data, it will be received in order. (Note that receive operations will never mix out-of-band and normal data in the same call.) lpvOutBuffer points at a BOOL in which WSAIoctl stores the result.

The following Windows Sockets 2 commands are supported:

SIO_ASSOCIATE_HANDLE (opcode setting: I, T==1)
Associate this socket with the specified handle of a companion interface. The input buffer contains the integer value corresponding to the manifest constant for the companion interface (for example, TH_NETDEV and TH_TAPI.), followed by a value that is a handle of the specified companion interface, along with any other required information. Refer to the appropriate section in the Windows Sockets 2 Protocol-Specific Annex (a separate document) for details specific to a particular companion interface. The total size is reflected in the input buffer length. No output buffer is required. The WSAENOPROTOOPT error code is indicated for service providers that do not support this ioctl. The handle associated by this ioctl can be retrieved using SIO_TRANSLATE_HANDLE.

A companion interface might be used, for example, if a particular provider provides (1) a great deal of additional controls over the behavior of a socket and (2) the controls are provider-specific enough that they do not map to existing Windows Socket functions or ones likely to be defined in the future. It is recommend that the Component Object Model (COM) be used instead of this ioctl to discover and track other interfaces that might be supported by a socket. This ioctl is present for (reverse) compatibility with systems where COM is not available or cannot be used for some other reason.

SIO_ENABLE_CIRCULAR_QUEUEING (opcode setting: V, T==1)
Indicates to the underlying message-oriented service provider that a newly arrived message should never be dropped because of a buffer queue overflow. Instead, the oldest message in the queue should be eliminated in order to accommodate the newly arrived message. No input and output buffers are required. Note that this ioctl is only valid for sockets associated with unreliable, message-oriented protocols. The WSAENOPROTOOPT error code is indicated for service providers that do not support this ioctl.
SIO_FIND_ROUTE (opcode setting: O, T==1)
When issued, this ioctl requests that the route to the remote address specified as a SOCKADDR in the input buffer be discovered. If the address already exists in the local cache, its entry is invalidated. In the case of Novell's IPX, this call initiates an IPX GetLocalTarget (GLT), which queries the network for the given remote address.
SIO_FLUSH (opcode setting: V, T==1)
Discards current contents of the sending queue associated with this socket. No input and output buffers are required. The WSAENOPROTOOPT error code is indicated for service providers that do not support this ioctl.
SIO_GET_BROADCAST_ADDRESS (opcode setting: O, T==1)
This ioctl fills the output buffer with a SOCKADDR structure containing a suitable broadcast address for use with sendto/WSASendTo.
SIO_GET_EXTENSION_FUNCTION_POINTER (opcode setting: O, I, T==1)
Retrieve a pointer to the specified extension function supported by the associated service provider. The input buffer contains a globally unique identifier (GUID) whose value identifies the extension function in question. The pointer to the desired function is returned in the output buffer. Extension function identifiers are established by service provider vendors and should be included in vendor documentation that describes extension function capabilities and semantics.
SIO_GET_QOS (opcode setting: O, T==1)
Reserved for future use with sockets. Retrieve the QUALITYOFSERVICE structure associated with the socket. The input buffer is optional. Some protocols (for example, RSVP) allow the input buffer to be used to qualify a quality of service request. The QUALITYOFSERVICE structure will be copied into the output buffer. The output buffer must be sized large enough to be able to contain the full QUALITYOFSERVICE structure. The WSAENOPROTOOPT error code is indicated for service providers that do not support quality of service.
SIO_GET_GROUP_QOS (opcode setting: O, I, T==1)
Retrieve the QUALITYOFSERVICE structure associated with the socket group to which this socket belongs. The input buffer is optional. Some protocols (for example, RSVP) allow the input buffer to be used to qualify a quality of service request. The QUALITYOFSERVICE structure will be copied into the output buffer. If this socket does not belong to an appropriate socket group, the SendingFlowspec and ReceivingFlowspec fields of the returned QUALITYOFSERVICE structure are set to NULL. The WSAENOPROTOOPT error code is indicated for service providers that do not support quality of service.
SIO_MULTIPOINT_LOOPBACK (opcode setting: I, T==1)
Controls whether data sent in a multipoint session will also be received by the same socket on the local host. A value of TRUE causes loopback reception to occur while a value of FALSE prohibits this. By default, loopback is enabled.
SIO_MULTICAST_SCOPE (opcode setting: I, T==1)
Specifies the scope over which multicast transmissions will occur. Scope is defined as the number of routed network segments to be covered. A scope of zero would indicate that the multicast transmission would not be placed "on the wire" but could be disseminated across sockets within the local host. A scope value of one (the default) indicates that the transmission will be placed on the wire, but will not cross any routers. Higher scope values determine the number of routers that can be crossed. Note that this corresponds to the time-to-live (TTL) parameter in IP multicasting. By default, scope is 1.
SIO_SET_QOS (opcode setting: I, T==1)
Associate the supplied QUALITYOFSERVICE structure with the socket. No output buffer is required, the QUALITYOFSERVICE structure will be obtained from the input buffer. The WSAENOPROTOOPT error code is indicated for service providers that do not support quality of service.
SIO_SET_GROUP_QOS(opcode setting: I, T==1)
Reserved for future use with sockets. Establish the supplied QUALITYOFSERVICE structure with the socket group to which this socket belongs. No output buffer is required, the QUALITYOFSERVICE structure will be obtained from the input buffer. The WSAENOPROTOOPT error code is indicated for service providers that do not support quality of service, or if the socket descriptor specified is not the creator of the associated socket group.
SIO_TRANSLATE_HANDLE (opcode setting: I, O, T==1)
To obtain a corresponding handle for socket s that is valid in the context of a companion interface (for example, TH_NETDEV and TH_TAPI). A manifest constant identifying the companion interface along with any other needed parameters are specified in the input buffer. The corresponding handle will be available in the output buffer upon completion of this function. Refer to the appropriate section in Windows Sockets 2 Protocol-Specific Annex for details specific to a particular companion interface. The WSAENOPROTOOPT error code is indicated for service providers that do not support this ioctl for the specified companion interface.This ioctl retrieves the handle associated using SIO_TRANSLATE_HANDLE.

It is recommend that the Component Object Model (COM) be used instead of this ioctl to discover and track other interfaces that might be supported by a socket. This ioctl is present for (reverse) compatibility with systems where COM is not available or cannot be used for some other reason.

SIO_ROUTING_INTERFACE_QUERY (opcode setting: I, O, T==1)
To obtain the address of the local interface (represented as SOCKADDR structure) which should be used to send to the remote address specified in the input buffer (as SOCKADDR). Remote multicast addresses may be submitted in the input buffer to get the address of the preferred interface for multicast transmission. In any case, the interface address returned may be used by the application in a subsequent bind() request.

Note that routes are subject to change. Therefore, applications cannot rely on the information returned by SIO_ROUTING_INTERFACE_QUERY to be persistent. Applications may register for routing change notifications via the SIO_ROUTING_INTERFACE_CHANGE IOCTL which provides for notification via either overlapped IO or FD_ROUTING_INTERFACE_CHANGE event. The following sequence of actions can be used to guarantee that the application always has current routing interface information for a given destination:

  • issue SIO_ROUTING_INTERFACE_CHANGE IOCTL
  • issue SIO_ROUTING_INTERFACE_QUERY IOCTL
  • whenever SIO_ROUTING_INTERFACE_CHANGE IOCTL notifies the application of routing change (either via overlapped IO or by signaling FD_ROUTING_INTERFACE_CHANGE event), the whole sequence of actions should be repeated.

If output buffer is not large enough to contain the interface address, SOCKET_ERROR is returned as the result of this IOCTL and WSAGetLastError returns WSAEFAULT. The required size of the output buffer will be returned in lpcbBytesReturned in this case. Note the WSAEFAULT error code is also returned if the lpvInBuffer, lpvOutBuffer or lpcbBytesReturned parameter is not totally contained in a valid part of the user address space.

If the destination address specified in the input buffer cannot be reached via any of the available interfaces, SOCKET_ERROR is returned as the result of this IOCTL and WSAGetLastError returns WSAENETUNREACH or even WSAENETDOWN if all of the network connectivity is lost.

SIO_ROUTING_INTERFACE_CHANGE (opcode setting: I, T==1)
To receive notification of the interface change that should be used to reach the remote address in the input buffer (specified as a SOCKADDR structure). No output information will be provided upon completion of this IOCTL; the completion merely indicates that routing interface for a given destination has changed and should be queried again via SIO_ROUTING_INTERFACE_QUERY.

It is assumed (although not required) that the application uses overlapped IO to be notified of routing interface change via completion of SIO_ROUTING_INTERFACE_CHANGE request. Alternatively, if the SIO_ROUTING_INTERFACE_CHANGE IOCTL is issued on non-blocking socket and without overlapped parameters (lpOverlapped / CompletionRoutine are set NULL), it will complete immediately with error WSAEWOULDBLOCK, and the application can then wait for routing change events via call to WSAEventSelect or WSAAsyncSelect with FD_ROUTING_INTERFACE_CHANGE bit set in the network event bitmask

It is recognized that routing information remains stable in most cases so that requiring the application to keep multiple outstanding IOCTLs to get notifications about all destinations that it is interested in as well as having service provider to keep track of all them will unnecessarily tie significant system resources. This situation can be avoided by extending the meaning of the input parameters and relaxing the service provider requirements as follows:

  • The application can specify a protocol family specific wildcard address (same as one used in bind call when requesting to bind to any available address) to request notifications of any routing changes. This allows the application to keep only one outstanding SIO_ROUTING_INTERFACE_CHANGE for all the sockets/destinations it has and then use SIO_ROUTING_INTERFACE_QUERY to get the actual routing information
  • Service provider has the option to ignore the information supplied by the application in the input buffer of the SIO_ROUTING_INTERFACE_CHANGE (as though the application specified a wildcard address) and complete the SIO_ROUTING_INTERFACE_CHANGE IOCTL or signal FD_ROUTING_INTERFACE_CHANGE event in the event of any routing information change (not just the route to the destination specified in the input buffer).
SIO_ADDRESS_LIST_QUERY (opcode setting: I, O, T==1)
To obtain a list of local transport addresses of socket's protocol family to which the application can bind. The list returned in the output buffer using the following format:
typedef struct _SOCKET_ADDRESS_LIST {
    INT iAddressCount;
    SOCKET_ADDRESS Address[1];
} SOCKET_ADDRESS_LIST, FAR * LPSOCKET_ADDRESS_LIST;
Members:
    iAddressCount - number of address structures in the list;
    Address - array of protocol family specific address structures.

Note that in Win32 Plug-n-Play environments addresses can be added/removed dynamically. Therefore, applications cannot rely on the information returned by SIO_ADDRESS_LIST_QUERY to be persistent. Applications may register for address change notifications via the SIO_ADDRESS_LIST_CHANGE IOCTL which provides for notification via either overlapped IO or FD_ADDRESS_LIST_CHANGE event. The following sequence of actions can be used to guarantee that the application always has current address list information:·issue SIO_ADDRESS_LIST_CHANGE IOCTL

  • issue SIO_ADDRESS_LIST_QUERY IOCTL
  • whenever SIO_ADDRESS_LIST_CHANGE IOCTL notifies the application of address list change (either via overlapped IO or by signaling FD_ADDRESS_LIST_CHANGE event), the whole sequence of actions should be repeated.

If output buffer is not large enough to contain the address list, SOCKET_ERROR is returned as the result of this IOCTL and WSAGetLastError returns WSAEFAULT. The required size of the output buffer will be returned in lpcbBytesReturned in this case. Note the WSAEFAULT error code is also returned if the lpvInBuffer, lpvOutBuffer or lpcbBytesReturned parameter is not totally contained in a valid part of the user address space.

SIO_ADDRESS_LIST_CHANGE (opcode setting: T==1)
To receive notification of changes in the list of local transport addresses of socket's protocol family to which the application can bind. No output information will be provided upon completion of this IOCTL; the completion merely indicates that list of available local address has changed and should be queried again via SIO_ADDRESS_LIST_QUERY.

It is assumed (although not required) that the application uses overlapped IO to be notified of change via completion of SIO_ADDRESS_LIST_CHANGE request. Alternatively, if the SIO_ADDRESS_LIST_CHANGE IOCTL is issued on non-blocking socket AND without overlapped parameters (lpOverlapped / lpCompletionRoutine are set to NULL), it will complete immediately with error WSAEWOULDBLOCK. The application can then wait for address list change events via call to WSAEventSelect or WSAAsyncSelect with FD_ADDRESS_LIST_CHANGE bit set in the network event bitmask.

If an overlapped operation completes immediately, WSAIoctl returns a value of zero and the lpcbBytesReturned parameter is updated with the number of bytes in the output buffer. If the overlapped operation is successfully initiated and will complete later, this function returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpcbBytesReturned is not updated. When the overlapped operation completes the amount of data in the output buffer is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSAGetOverlappedResult.

When called with an overlapped socket, the lpOverlapped parameter must be valid for the duration of the overlapped operation. The lpOverlapped parameter contains the address of a WSAOVERLAPPED structure.

If the lpCompletionRoutine parameter is NULL, the hEvent field of lpOverlapped is signaled when the overlapped operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or WSAGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the application to pass context information to the completion routine. A caller that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

The prototype of the completion routine is as follows:

void CALLBACK CompletionRoutine(
  IN  DWORD dwError,
  IN  DWORD cbTransferred,
  IN  LPWSAOVERLAPPED lpOverlapped,
  IN  DWORD dwFlags
);

This CompletionRoutine is a placeholder for an application-defined or library-defined function. The dwError parameter specifies the completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred parameter specifies the number of bytes returned. Currently, there are no flag values defined and dwFlags will be zero. The CompletionRoutine function does not return a value.

Returning from this function allows invocation of another pending completion routine for this socket. The completion routines can be called in any order, not necessarily in the same order the overlapped operations are completed.

Windows CE: For secure sockets, the lpcbBytesReturned parameter is a pointer to a DWORD receiving the number of bytes returned in output buffer. Also, the last two parameters, namely, lpOverlapped and lpCompletionRoutine, must be NULL.

In addition to the ioctlsocket control codes (FIONBIO, SIOCATMARK, FIONREAD), the dwIoControlCode parameter may also assume the following SSL-specific control flags:

Value | Meaning
SO_SSL_GET_CAPABILITIES | Retrieves a set of flags describing the WinSock security provider's capabilities. The output buffer must be a pointer to a DWORD bit field. At present, only the SO_CAP_CLIENT flag is defined.
SO_SSL_GET_FLAGS | Retrieves s-channel specific flags associated with a particular socket. The output buffer must be a pointer to a DWORD bit field. See SO_SSL_SET_FLAGS for details on valid flags.
SO_SSL_SET_FLAGS Sets the sockets' current s-channel-specific flag values. The input buffer must be a pointer to a DWORD bit field. Currently, only the SSL_FLAG_DEFER_HANDSHAKE flag is defined to allow the application to send and receive plain text data before switching to cipher text. It is required for setting up communication through proxy servers.

Normally the WinSock security provider performs the secure handshake in the WinSock connect API. However, if this flag is set, the handshake is deferred until the application issues the SO_SSL_PERFORM_HANDSHAKE control code. After the handshaking, this flag is reset.

SO_SSL_GET_PROTOCOLS Retrieves a list of protocols that the provider currently supports on this socket. The output buffer must be a pointer to a SSLPROTOCOLS structure as described below:
typedef struct _SSLPROTOCOL {
     DWORD dwProtocol;
     DWORD dwVersion;
     DWORD dwFlags;
} SSLPROTOCOL, *LPSSLPROTOCOL;
typedef struct _SSLPROTOCOLS {
     DWORD dwCount;
     SSLPROTOCOL ProtocolList[1];
} SSLPROTOCOLS, FAR *LPSSLPROTOCOLS;

Valid protocols include SSL_PROTOCOL_SSL2, SSL_PROTOCOL_SSL3, and SSL_PROTOCOL_PCT1.
SO_SSL_SET_PROTOCOLS | Specifies a list of protocols the provider is to support on this socket. The input buffer must be a pointer to SSLPROTOCOLS structure described above.
SO_SSL_SET_VALIDATE_CERT_HOOK Sets the pointer to the socket's certificate validation hook. It is used to specify the callback function invoked by the WinSock security provider when a set of credentials is received from the remote party. The input buffer must be a pointer to the SSLVALIDEATECERTHOOK structure, described below:
typedef struct {
      SSLVALIDATECERTFUNC HookFunc;
      LPVOID pvArg;
} SSLVALIDATEPROTOCOLCERTHOOK, *PSSLVALIDATECERTHOOK;

where HookFunc is a pointer to the certificate validation callback function (see "Certificate Validation Callback" below). pvArg is a pointer to application specific data and may be used by the application for any purpose.
SO_SSL_PERFORM_HANDSHAKE | Initiates the secure handshake sequence on a connected socket where the SSL_FLAG_DEFER_HANDSHAKE flag has been set prior to the connection. Data buffers are not required, but the SSL_FLAG_DEFER_HANDSHAKE flag will be reset.

Certificate Validation Callback

The WinSock security provider invokes the certificate validation callback when the remote party receives a certificate for server authentication. All the client applications must implement the callback function to ensure that the certificate should meet the following minimum requirements:

  • The certificate has not expired;
  • The identity contained within the certificate matches that of the remote party.

The certificate validation callback function is of the following type:

typedef int (CALLBACK *SSLVALIDATECERTFUNC){
DWORD dwType, // in
LPVOID pvArg, // in
DWORD dwChainLen, // in
LPBLOB pCertChain, // in
DWORD dwFlags // in
};

The parameters are defined in the following table.

Parameters | Meaning
dwType | Specifies the type of data pointed to be pCertChain. This must be SSL_CERT_X59 to specify that pCertChain be a pointer to an X509 style certificate.
PvArg | An application-defined context passed into the SSLVALIDATECERTHOOK structure.
DwChainLen | The number of certificates pointed to by pCertChain. In Windows CE this will always be one.
PCertChain | Pointer to the remote party's certificate.
DwFlags | To be designed to indicate that the certificate issuer list has been checked with the list of known certificate authorities and that the certificate is either trusted or not. This is required since not all the certificate chain is passed to the application.

The application-defined callback function will typically return one of the following error codes:

Value | Meaning
SSL_ERR_OKAY | The remote party's certificate is acceptable.
SSL_ERR_BAD_DATA | The certificate is improperly formatted.
SSL_ERR_BAD_SIG | The signature check fails.
SSL_ERR_CERT_EXPIRED | The certificate has expired.
SSL_ERR_CERT_REVOKED | The certificate has been revoked by its issuer.
SSL_ERR_CERT_UNKNOWN | The issuer of the certificate is not recognized or some unspecified issue arose in the processing of the certificate, rendering it unacceptable.

Compatibility

The ioctl codes with T == 0 are a subset of the ioctl codes used in Berkeley sockets. In particular, there is no command that is equivalent to FIOASYNC.

Return Values

Upon successful completion, the WSAIoctl returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The lpvInBuffer, lpvOutBuffer lpcbBytesReturned, lpOverlapped, or lpCompletionRoutine argument is not totally contained in a valid part of the user address space, or the cbInBuffer or cbOutBuffer argument is too small.
WSAEINVAL | dwIoControlCode is not a valid command, or a supplied input parameter is not acceptable, or the command is not applicable to the type of socket supplied.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAENOTSOCK | The descriptor s is not a socket.
WSAEOPNOTSUPP | The specified ioctl command cannot be realized. (For examle, the FLOWSPEC structures specified in SIO_SET_QOS or SIO_SET_GROUP_QOS cannot be satisfied.)
WSA_IO_PENDING | An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the requested operation would block.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getsockopt, ioctlsocket, setsockopt, socket, WSASocket


WSAIsBlocking

This function has been removed in compliance with the Windows Sockets 2 specification, revision 2.2.0.

The function is not exported directly by the WS2_32.DLL, and Windows Sockets 2 applications should not use this function. Windows Sockets 1.1 applications that call this function are still supported through the WINSOCK.DLL and WSOCK32.DLL.

Blocking hooks are generally used to keep a single-threaded GUI application responsive during calls to blocking functions. Instead of using blocking hooks, an applications should use a separate thread (separate from the main GUI thread) for network activity.


WSAJoinLeaf

The Windows Sockets WSAJoinLeaf function joins a leaf node into a multipoint session, exchanges connect data, and specifies needed quality of service based on the supplied FLOWSPEC structures.

SOCKET WSAJoinLeaf (
  SOCKET s,
  const struct sockaddr FAR * name,
  int namelen,
  LPWSABUF lpCallerData,
  LPWSABUF lpCalleeData,
  LPQOS lpSQOS,
  LPQOS lpGQOS,
  DWORD dwFlags
);

Parameters

s
[in] A descriptor identifying a multipoint socket.
name
[in] The name of the peer to which the socket is to be joined.
namelen
[in] The length of the name.
lpCallerData
[in] A pointer to the user data that is to be transferred to the peer during multipoint session establishment.
lpCalleeData
[out] A pointer to the user data that is to be transferred back from the peer during multipoint session establishment.
lpSQOS
[in] A pointer to the FLOWSPEC structures for socket s, one for each direction.
lpGQOS
[in] Reserved for future use with socket groups. A pointer to the FLOWSPEC structures for the socket group (if applicable).
dwFlags
[in] Flags to indicate that the socket is acting as a sender, receiver, or both.

Remarks

The WSAJoinLeaf function is used to join a leaf node to a multipoint session, and to perform a number of other ancillary operations that occur at session join time as well. If the socket, s, is unbound, unique values are assigned to the local association by the system, and the socket is marked as bound.

The WSAJoinLeaf function has the same parameters and semantics as WSAConnect except that it returns a socket descriptor (as in WSAAccept ), and it has an additional dwFlags parameter. Only multipoint sockets created using WSASocket with appropriate multipoint flags set can be used for input parameter s in this function. The returned socket descriptor will not be useable until after the join operation completes. For example, if the socket is in nonblocking mode after a corresponding FD_CONNECT indication has been received from WSAAsyncSelect or WSAEventSelect on the original socket s, except that closesocket may be invoked on this new socket descriptor to cancel a pending join operation. A root application in a multipoint session may call WSAJoinLeaf one or more times in order to add a number of leaf nodes, however at most one multipoint connection request may be outstanding at a time. Refer to Multipoint and Multicast Semantics for additional information.

For nonblocking sockets it is often not possible to complete the connection immediately. In such a case, this function returns an as-yet unusable socket descriptor and the operation proceeds. There is no error code such as WSAEWOULDBLOCK in this case, since the function has effectively returned a "successful start" indication. When the final outcome success or failure becomes known, it may be reported through WSAAsyncSelect or WSAEventSelect depending on how the client registers for notification on the original socket s. In either case, the notification is announced with FD_CONNECT and the error code associated with the FD_CONNECT indicates either success or a specific reason for failure. The select function cannot be used to detect completion notification for WSAJoinLeaf.

The socket descriptor returned by WSAJoinLeaf is different depending on whether the input socket descriptor, s, is a c_root or a c_leaf. When used with a c_root socket, the name parameter designates a particular leaf node to be added and the returned socket descriptor is a c_leaf socket corresponding to the newly added leaf node. The newly created socket has the same properties as s including asynchronous events registered with WSAAsyncSelect or with WSAEventSelect, but not including the c_root socket's group ID, if any. It is not intended to be used for exchange of multipoint data, but rather is used to receive network event indications (for example, FD_CLOSE) for the connection that exists to the particular c_leaf. Some multipoint implementations can also allow this socket to be used for "side chats" between the root and an individual leaf node. An FD_CLOSE indication will be received for this socket if the corresponding leaf node calls closesocket to drop out of the multipoint session. Symmetrically, invoking closesocket on the c_leaf socket returned from WSAJoinLeaf will cause the socket in the corresponding leaf node to get FD_CLOSE notification.

When WSAJoinLeaf is invoked with a c_leaf socket, the name parameter contains the address of the root application (for a rooted control scheme) or an existing multipoint session (nonrooted control scheme), and the returned socket descriptor is the same as the input socket descriptor. In other words, a new socket descriptor is not allocated. In a rooted control scheme, the root application would put its c_root socket in the listening mode by calling listen. The standard FD_ACCEPT notification will be delivered when the leaf node requests to join itself to the multipoint session. The root application uses the usual accept /WSAAccept functions to admit the new leaf node. The value returned from either accept or WSAAccept is also a c_leaf socket descriptor just like those returned from WSAJoinLeaf. To accommodate multipoint schemes that allow both root-initiated and leaf-initiated joins, it is acceptable for a c_root socket that is already in listening mode to be used as an input to WSAJoinLeaf.

The application is responsible for allocating any memory space pointed to directly or indirectly by any of the parameters it specifies.

The lpCallerData is a value parameter that contains any user data that is to be sent along with the multipoint session join request. If lpCallerData is NULL, no user data will be passed to the peer. The lpCalleeData is a result parameter that will contain any user data passed back from the peer as part of the multipoint session establishment. The lpCalleeData->len initially contains the length of the buffer allocated by the application and pointed to by lpCalleeData->buf. lpCalleeData->len will be set to zero if no user data has been passed back. The lpCalleeData information will be valid when the multipoint join operation is complete. For blocking sockets, this will be when the WSAJoinLeaf function returns. For nonblocking sockets, this will be after the join operation has completed. For example, this could occur after FD_CONNECT notification on the original socket s). If lpCalleeData is NULL, no user data will be passed back. The exact format of the user data is specific to the address family to which the socket belongs.

At multipoint session establishment time, an application can use the lpSQOS and/or lpGQOS parameters to override any previous quality of service specification made for the socket through WSAIoctl with either the SIO_SET_QOS or SIO_SET_GROUP_QOS opcodes.

The lpSQOS parameter specifies the FLOWSPEC structures for socket s, one for each direction, followed by any additional provider-specific parameters. If either the associated transport provider in general or the specific type of socket in particular cannot honor the quality of service request, an error will be returned as indicated below. The sending or receiving flow specification values will be ignored, respectively, for any unidirectional sockets. If no provider-specific parameters are supplied, the buf and len fields of lpSQOS->ProviderSpecific should be set to NULL and zero, respectively. A NULL value for lpSQOS indicates no application supplied quality of service.

Reserved for future socket groups. The lpGQOS parameter specifies the FLOWSPEC structures for the socket group (if applicable), one for each direction, followed by any additional provider-specific parameters. If no provider-specific parameters are supplied, the buf and len fields of lpGQOS->ProviderSpecific should be set to NULL and zero, respectively. A NULL value for lpGQOS indicates no application-supplied group quality of service. This parameter will be ignored if s is not the creator of the socket group.

The dwFlags parameter is used to indicate whether the socket will be acting only as a sender (JL_SENDER_ONLY), only as a receiver (JL_RECEIVER_ONLY), or both (JL_BOTH).

When connected sockets break (that is, become closed for whatever reason), they should be discarded and recreated. It is safest to assume that when things go awry for any reason on a connected socket, the application must discard and recreate the needed sockets in order to return to a stable point.

Return Values

If no error occurs, WSAJoinLeaf returns a value of type SOCKET that is a descriptor for the newly created multipoint socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.

On a blocking socket, the return value indicates success or failure of the join operation.

With a nonblocking socket, successful initiation of a join operation is indicated by a return of a valid socket descriptor. Subsequently, an FD_CONNECT indication will be given on the original socket s when the join operation completes, either successfully or otherwise. The application must use either WSAAsyncSelect or WSAEventSelect with interest registered for the FD_CONNECT event in order to determine when the join operation has completed and checks the associated error code to determine the success or failure of the operation. The select function cannot be used to determine when the join operation completes.

Also, until the multipoint session join attempt completes all subsequent calls to WSAJoinLeaf on the same socket will fail with the error code WSAEALREADY. After the WSAJoinLeaf operation completes successfully, a subsequent attempt will usually fail with the error code WSAEISCONN. An exception to the WSAEISCONN rule occurs for a c_root socket that allows root-initiated joins. In such a case, another join may be initiated after a prior WSAJoinLeaf operation completes.

If the return error code indicates the multipoint session join attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the application can call WSAJoinLeaf again for the same socket.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs at the time of bind, but could be delayed until this function if the bind was to a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be "committed" at the time of this function.
WSAEINTR | A blockingWindows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEALREADY | A nonblocking WSAJoinLeaf call is in progress on the specified socket.
WSAEADDRNOTAVAIL | The remote address is not a valid address (such as ADDR_ANY).
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to join was forcefully rejected.
WSAEFAULT | The name or the namelen parameter is not a valid part of the user address space, the namelen parameter is too small, the buffer length for lpCalleeData, lpSQOS, and lpGQOS are too small, or the buffer length for lpCallerData is too large.
WSAEISCONN | The socket is already member of the multipoint session.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAENOBUFS | No buffer space is available. The socket cannot be joined.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The FLOWSPEC structures specified in lpSQOS and lpGQOS cannot be satisfied.
WSAEPROTONOSUPPORT | The lpCallerData augment is not supported by the service provider.
WSAETIMEDOUT | Attempt to join timed out without establishing a multipoint session.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, bind, select, WSAAccept, WSAAsyncSelect, WSAEventSelect, WSASocket


WSALookupServiceBegin

The Windows Sockets WSALookupServiceBegin function initiates a client query that is constrained by the information contained within a WSAQUERYSET structure. WSALookupServiceBegin only returns a handle, which should be used by subsequent calls to WSALookupServiceNext to get the actual results.

INT WSALookupServiceBegin (
  LPWSAQUERYSET lpqsRestrictions,
  DWORD dwControlFlags,
  LPHANDLE lphLookup
);

Parameters

lpqsRestrictions
[in] A pointer to the search criteria. See below for details.
dwControlFlags
[in] A flag that controls the depth of the search.
LUP_DEEP | Query deep as opposed to just the first level.
LUP_CONTAINERS | Return containers only
LUP_NOCONTAINERS | Do not return any containers
LUP_FLUSHCACHE | If the provider has been caching information, ignore the cache and go query the name space itself.
LUP_FLUSHPREVIOUS | Used as a value for the dwControlFlags argument in WSALookupServiceNext. Setting this flag instructs the provider to discard the last result set, which was too large for the supplied buffer, and move on to the next result set.
LUP_NEAREST | If possible, return results in the order of distance. The measure of distance is provider specific.
LUP_RES_SERVICE | This indicates whether prime response is in the remote or local part of CSADDR_INFO structure. The other part needs to be "usable" in either case.
LUP_RETURN_ALIASES | Any available alias information is to be returned in successive calls to WSALookupServiceNext, and each alias returned will have the RESULT_IS_ALIAS flag set.
LUP_RETURN_NAME | Retrieve the nameas lpszServiceInstanceName.
LUP_RETURN_TYPE | Retrieve the type as lpServiceClassId.
LUP_RETURN_VERSION | Retrieve the version as lpVersion.
LUP_RETURN_COMMENT | Retrieve the comment as lpszComment.
LUP_RETURN_ADDR | Retrieve the addresses as lpcsaBuffer.
LUP_RETURN_BLOB | Retrieve the private data as lpBlob.
LUP_RETURN_ALL | Retrieve all of the information

lphLookup
[out] A handle to be used when calling WSALookupServiceNext in order to start retrieving the results set.

Remarks

If LUP_CONTAINERS is specified in a call, all other restriction values should be avoided. If any are supplied, it is up to the name service provider to decide if it can support this restriction over the containers. If it cannot, it should return an error.

Some name service providers can have other means of finding containers. For example, containers might all be of some well-known type, or of a set of well-known types, and therefore a query restriction can be created for finding them. No matter what other means the name service provider has for locating containers, LUP_CONTAINERS and LUP_NOCONTAINERS take precedence. Hence, if a query restriction is given that includes containers, specifying LUP_NOCONTAINERS will prevent the container items from being returned. Similarly, no matter the query restriction, if LUP_CONTAINERS is given, only containers should be returned. If a name space does not support containers, and LUP_CONTAINERS is specified, it should simply return WSANO_DATA.

The preferred method of obtaining the containers within another container, is the call:

dwStatus = WSALookupServiceBegin(
      lpqsRestrictions,
      LUP_CONTAINERS,
      lphLookup);

This call is followed by the requisite number of WSALookupServiceNext calls. This will return all containers contained immediately within the starting context; that is, it is not a deep query. With this, one can map the address space structure by walking the hierarchy, perhaps enumerating the content of selected containers. Subsequent uses of WSALookupServiceBegin use the containers returned from a previous call.

As mentioned above, a WSAQUERYSET structure is used as an input parameter to WSALookupBegin in order to qualify the query. The following table indicates how the WSAQUERYSET is used to construct a query. When a field is marked as (Optional) a NULL pointer can be supplied, indicating that the field will not be used as a search criteria. See section Query-Related Data Structures for additional information.

WSAQUERYSET Field Name | Query Interpretation
dwSize | Must be set to sizeof(WSAQUERYSET). This is a versioning mechanism.
DwOutputflags | Ignored for queries.
LpszServiceInstanceName | (Optional) Referenced string contains service name. The semantics for wildcarding within the string are not defined, but can be supported by certain name space providers.
LpServiceClassId | (Required) The GUID corresponding to the service class.
LpVersion | (Optional) References desired version number and provides version comparison semantics (that is, version must match exactly, or version must be not less than the value supplied).
LpszComment | Ignored for queries.
DwNameSpace1 | Identifier of a single name space in which to constrain the search, or NS_ALL to include all name spaces.
LpNSProviderId | (Optional) References the GUID of a specific name space provider, and limits the query to this provider only.
LpszContext | (Optional) Specifies the starting point of the query in a hierarchical name space.
DwNumberOfProtocols | Size of the protocol constraint array, can be zero.
LpafpProtocols | (Optional) References an array of AFPROTOCOLS structure. Only services that utilize these protocols will be returned.
LpszQueryString | (Optional) Some namespaces (such as whois++) support enriched SQL like queries that are contained in a simple text string. This parameter is used to specify that string.
DwNumberOfCsAddrs | Ignored for queries.
LpcsaBuffer | Ignored for queries.
LpBlob | (Optional) This is a pointer to a provider-specific entity.
1 See the Important note below

Important In most instances, applications interested in only a particular transport protocol should constrain their query by address family and protocol rather than by name space. This would allow an application that needs to locate a TCP/IP service, for example, to have its query processed by all available name spaces such as the local hosts file, DNS, and NIS.

Return Values

The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSAEINVAL | One ormore parameters were missing or invalid for this provider.
WSANO_DATA | The name was found in the database but no data matching the given restrictions was located.
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
WSASERVICE_NOT_FOUND | No such service is known. The service cannot be found in the specified name space.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSALookupServiceEnd, WSALookupServiceNext


WSALookupServiceEnd

The Windows Sockets WSALookupServiceEnd function is called to free the handle after previous calls to WSALookupServiceBegin and WSALookupServiceNext.

If you call WSALookupServiceEnd from another thread while an existing WSALookupServiceNext is blocked, the end call will have the same effect as a cancel and will cause the WSALookupServiceNext call to return immediately.

INT WSALookupServiceEnd (
  HANDLE hLookup
);

Parameters

hLookup
[in] A handle previously obtained by calling WSALookupServiceBegin.

Return Values

The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSA_INVALID_HANDLE | The handle is not valid
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Socketsfunctions.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSALookupServiceBegin, WSALookupServiceNext


WSALookupServiceNext

The Windows Sockets WSALookupServiceNext function is called after obtaining a handle from a previous call to WSALookupServiceBegin in order to retrieve the requested service information.

The provider will pass back a WSAQUERYSET structure in the lpqsResults buffer. The client should continue to call this function until it returns WSA_E_NOMORE, indicating that all of WSAQUERYSET has been returned.

INT WSALookupServiceNext (
  HANDLE hLookup,
  DWORD dwControlFlags,
  LPDWORD lpdwBufferLength,
  LPWSAQUERYSET lpqsResults
);

Parameters

hLookup
[in] A handle returned from the previous call to WSALookupServiceBegin.
dwControlFlags
[in] Flags to control the next operation. Currently only LUP_FLUSHPREVIOUS is defined as a means to cope with a result set which is too large. If an application does not wish to (or cannot) supply a large enough buffer, setting LUP_FLUSHPREVIOUS instructs the provider to discard the last result set - which was too large - and move on to the next set for this call.
lpdwBufferLength
[in/out] On input, the number of bytes contained in the buffer pointed to by lpqsResults. On output, if the function fails and the error is WSAEFAULT, then it contains the minimum number of bytes to pass for the lpqsResults to retrieve the record.
lpqsResults
[out] A pointer to a block of memory, which will contain one result set in a WSAQUERYSET structure on return.

Remarks

The dwControlFlags specified in this function and the ones specified at the time of WSALookupServiceBegin are treated as "restrictions" for the purpose of combination. The restrictions are combined between the ones at WSALookupServiceBegin time and the ones at WSALookupServiceNext time. Therefore the flags at WSALookupServiceNext can never increase the amount of data returned beyond what was requested at WSALookupServiceBegin, although it is NOT an error to specify more or fewer flags. The flags specified at a given WSALookupServiceNext apply only to that call.

The dwControlFlags LUP_FLUSHPREVIOUS and LUP_RES_SERVICE are exceptions to the "combined restrictions" rule (because they are "behavior" flags instead of "restriction" flags). If either of these flags are used in WSALookupServiceNext they have their defined effect regardless of the setting of the same flags at WSALookupServiceBegin.

For example, if LUP_RETURN_VERSION is specified at WSALookupServiceBegin the service provider retrieves records including the "version". If LUP_RETURN_VERSION is NOT specified at WSALookupServiceNext, the returned information does not include the "version", even though it was available. No error is generated.

Also for example, if LUP_RETURN_BLOB is NOT specified at WSALookupServiceBegin but is specified at WSALookupServiceNext, the returned information does not include the private data. No error is generated.

Query Results

The following table describes how the query results are represented in the WSAQUERYSET structure.

WSAQUERYSET Field Name | Result Interpretation
dwSize | Will be set to sizeof(WSAQUERYSET). This is used as a versioning mechanism.
DwOuputFlags | RESULT_IS_ALIAS flag indicates this is an alias result.
LpszServiceInstanceName | Referenced string contains service name.
LpServiceClassId | The GUID corresponding to the service class.
LpVersion | References version number of the particular service instance.
LpszComment | Optional comment string supplied by service instance.
DwNameSpace | Name space in which the service instance was found.
LpNSProviderId | Identifies the specific name space provider that supplied this query result.
LpszContext | Specifies the context point in a hierarchical name space at which the service is located.
DwNumberOfProtocols | Undefined for results.
LpafpProtocols | Undefined for results, all needed protocol information is in the CSADDR_INFO structures.
LpszQueryString | When dwControlFlags includes LUP_RETURN_QUERY_STRING, this field returns the unparsed remainder of the lpszServiceInstanceName specified in the original query. For example, in a name space that identifies services by hierarchical names that specify a host name and a file path within that host, the address returned might be the host address and the unparsed remainder might be the file path. If the lpszServiceInstanceName is fully parsed and LUP_RETURN_QUERY_STRING is used, this field is NULL or points to a zero-length string.
DwNumberOfCsAddrs | Indicates the number of elements in the array of CSADDR_INFO structures.
LpcsaBuffer | A pointer to an array of CSADDR_INFO structures, with one complete transport address contained within each element.
LpBlob | (Optional) This is a pointer to a provider-specific entity.

Return Values

The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSA_E_NO_MORE | There is no more data available. In Windows Sockets version 2, conflicting error codes are defined for WSAENOMORE (10102) and WSA_E_NO_MORE (10110). The error code WSAENOMORE will be removed in a future version and only WSA_E_NO_MORE will remain. For Windows Sockets version 2, however, applications should check for both WSAENOMORE and WSA_E_NO_MORE for the widest possible compatibility with Name Space Providers that use either one.
WSA_E_CANCELLED | A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. The data in the lpqsResults buffer is undefined. In Windows Sockets version 2, conflicting error codes are defined for WSAECANCELLED (10103) and WSA_E_CANCELLED (10111). The error code WSAECANCELLED will be removed in a future version and only WSA_E_CANCELLED will remain. For Windows Sockets version 2, however, applications should check for both WSAECANCELLED and WSA_E_CANCELLED for the widest possible compatibility with Name Space Providers that use either one.
WSAEFAULT | The lpqsResults buffer was too small to contain a WSAQUERYSET set.
WSAEINVAL | One or more required parameters were invalid or missing.
WSA_INVALID_HANDLE | The specified Lookup handle is invalid.
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
WSANO_DATA | The name was ound in the database, but no data matching the given restrictions was located.
WSASERVICE_NOT_FOUND | No such service is known. The service cannot be found in the specified name space.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSALookupServiceBegin, WSALookupServiceEnd


WSANtohl

The Windows Sockets WSANtohl function converts a u_long from network byte order to host byte order.

int WSANtohl (
  SOCKET s,
  u_long netlong,
  u_long FAR * lphostlong
);

Parameters

s
[in] A descriptor identifying a socket.
netlong
[in] A 32-bit number in network byte order.
lphostlong
[out] A pointer to a 32-bit number in host byte order.

Remarks

The WSANtohl function takes a 32-bit number in the network byte order associated with socket s and returns a 32-bit number pointed to by the lphostlong parameter in host byte order.

Return Values

If no error occurs, WSANtohl returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lphostlong parameter is not completely contained in a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

htonl, htons, ntohl, ntohs, WSAHtonl, WSAHtons, WSANtohs


WSANtohs

The Windows Sockets WSANtohs function converts a u_short from network byte order to host byte order.

int WSANtohs (
  SOCKET s,
  u_short netshort,
  u_short FAR * lphostshort
);

Parameters

s
[in] A descriptor identifying a socket.
netshort
[in] A 16-bit number in network byte order.
lphostshort
[out] A pointer to a 16-bit number in host byte order.

Remarks

The WSANtohs function takes a 16-bit number in the network byte order associated with socket s and returns a 16-bit number pointed to by the lphostshort parameter in host byte order.

Return Values

If no error occurs, WSANtohs returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lphostshort parameter is not completely contained in a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

htonl, htons, ntohl, ntohs, WSAHtonl, WSANtohl, WSAHtons


WSAProviderConfigChange

The WSAProviderConfigChange function notifies the application when the provider configuration is changed.

int WSAAPI
WSAProviderConfigChange(
  LPHANDLE lpNotificationHandle,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Parameters

lpNotificationHandle
(in/out) A pointer to notification handle; if the notification handle is set to NULL (the handle value not the pointer itself), this function returns notification handle in the location pointed by lpNotificationHandle.
lpOverlapped
(in) A pointer to a WSAOVERLAPPED structure.
lpCompletionRoutine
(in) A pointer to the completion routine called when the provider change notification is received.

Remarks

The WSAProviderConfigChange function notifies the application of provider (both transport and name space) installation or removal in Win32 operating environments that support such configuration change without requiring a restart. When called for the first time (lpNotificationHandle parameter points to NULL handle), this function completes immediately and returns notification handle in the location pointed by lpNotificationHandle that can be used in subsequent calls to receive notifications of provider installation and removal. The second and any subsequent calls only complete when provider information changes since the time the call was made It is expected (but not required) that that application uses overlapped I/O on second and subsequent calls to WSAProviderConfigChange, in which case the call will return immediately and application will be notified of provider configuration changes using the completion mechanism chosen through specified overlapped completion parameters.

Notification handle returned by WSAProviderConfigChange is like any regular operating system handle that should be closed (when no longer needed) using Win32 CloseHandle call.

The following sequence of actions can be used to guarantee that application always has current protocol configuration information:

  • call WSAProviderConfigChange
  • call WSAEnumProtocols and/or WSAEnumNameSpaceProviders
  • whenever WSAProviderConfigChange notifies application of provider configuration change (via blocking or overlapped IO), the whole sequence of actions should be repeated

Return Values

If no error occurs the WSAProviderConfigChange returns 0. Otherwise, a value of SOCKET_ERROR is returned and a specific error code may be retrieved by calling WSAGetLastError. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion (and thus change event) will be indicated at a later time

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSA_NOT_ENOUGH _MEMORY | Not enough free memory available to complete the operation.
WSA_INVALID_HANDLE | Value pointed by lpNotificationHandle parameter is not a valid notification handle.
WSAEOPNOTSUPP | Current operating system environment does not support provider installation or removal without restart.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws_32.lib.

See Also

WSAEnumProtocols, WSAEnumNameSpaceProviders


WSARecv

The Windows Sockets WSARecv function receives data from a connected socket.

int WSARecv (
  SOCKET s,
  LPWSABUF lpBuffers,
  DWORD dwBufferCount,
  LPDWORD lpNumberOfBytesRecvd,
  LPDWORD lpFlags,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE
);

Parameters

s
[in] A descriptor identifying a connected socket.
lpBuffers
[in/out] A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length of the buffer.
dwBufferCount
[in] The number of WSABUF structures in the lpBuffers array.
lpNumberOfBytesRecvd
[out] A pointer to the number of bytes received by this call if the receive operation completes immediately.
lpFlags
[in/out] A pointer to flags.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the receive operation has been completed (ignored for nonoverlapped sockets).

Remarks

The WSARecv function provides functionality over and above the standard recv function in three important areas:

  1. It can be used in conjunction with overlapped sockets to perform overlapped receive operations.
  2. It allows multiple receive buffers to be specified making it applicable to the scatter/gather type of I/O.
  3. The lpFlags parameter is both an input and an output parameter, allowing applications to sense the output state of the MSG_PARTIAL flag bit. However, the MSG_PARTIAL flag bit is not supported by all protocols.

The WSARecv function is used on connected sockets or bound connectionless sockets specified by the s parameter and is used to read incoming data.The socket's local address must be known. For server applications, this is usually done explicitly through bind or implicitly through accept or WSAAccept. Explicit binding is discouraged for client applications. For client applications the socket can become bound implicitly to a local address through connect, WSAConnect, sendto, WSASendTo, or WSAJoinLeaf.

For connected, connectionless sockets, this function restricts the addresses from which received messages are accepted. The function only returns messages from the remote address specified in the connection. Messages from other addresses are (silently) discarded.

For overlapped sockets, WSARecv is used to post one or more buffers into which incoming data will be placed as it becomes available, after which the application-specified completion indication (invocation of the completion routine or setting of an event object) occurs. If the operation does not complete immediately, the final completion status is retrieved through the completion routine or WSAGetOverlappedResult.

If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a nonoverlapped socket.

For nonoverlapped sockets, the blocking semantics are identical to that of the standard recv function and the lpOverlapped and lpCompletionRoutine parameters are ignored. Any data that has already been received and buffered by the transport will be copied into the supplied user buffers. In the case of a blocking socket with no data currently having been received and buffered by the transport, the call will block until data is received. Windows Socket 2 does not define any standard blocking timeout mechanism for this function. For protocols acting as byte-stream protocols the stack tries to return as much data as possible subject to the supplied buffer space and amount of received data available. However, receipt of a single byte is sufficient to unblock the caller. There is no guarantee that more than a single byte will be returned. For protocols acting as message-oriented, a full message is required to unblock the caller.

Whether or not a protocol is acting as byte-stream is determined by the setting of XP1_MESSAGE_ORIENTED and XP1_PSEUDO_STREAM in its WSAPROTOCOL_INFO structure and the setting of the MSG_PARTIAL flag passed in to this function (for protocols that support it). The relevant combinations are summarized in the following table (an asterisk (*) indicates that the setting of this bit does not matter in this case).

XP1_MESSAGE _ORIENTED | XP1_PSEUDO _STREAM | MSG_PARTIAL | Acts as
not set | * | * | byte-stream
* | set | * | byte-stream
set | not set | set | byte-stream
set | not set | not set | message-oriented

The supplied buffers are filled in the order in which they appear in the array pointed to by lpBuffers, and the buffers are packed so that no holes are created.

The array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation completes in an overlapped manner, it is the service provider's responsibility to capture these WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays.

For byte stream-style sockets (for example, type SOCK_STREAM), incoming data is placed into the buffers until the buffers are filled, the connection is closed, or the internally buffered data is exhausted. Regardless of whether or not the incoming data fills all the buffers, the completion indication occurs for overlapped sockets.

For message-oriented sockets (for example, type SOCK_DGRAM), an incoming message is placed into the supplied buffers up to the total size of the buffers supplied, and the completion indication occurs for overlapped sockets. If the message is larger than the buffers supplied, the buffers are filled with the first part of the message. If the MSG_PARTIAL feature is supported by the underlying service provider, the MSG_PARTIAL flag is set in lpFlags and subsequent receive operations will retrieve the rest of the message. If MSG_PARTIAL is not supported but the protocol is reliable, WSARecv generates the error WSAEMSGSIZE and a subsequent receive operation with a larger buffer can be used to retrieve the entire message. Otherwise, (that is, the protocol is unreliable and does not support MSG_PARTIAL), the excess data is lost, and WSARecv generates the error WSAEMSGSIZE.

For connection-oriented sockets, WSARecv can indicate the graceful termination of the virtual circuit in one of two ways that depend on whether the socket is a byte stream or message oriented. For byte streams, zero bytes having been read (as indicated by zero return value to indicate success, and lpNumberOfBytesRecvd value of zero) indicates graceful closure and that no more bytes will ever be read. For message-oriented sockets, where a zero byte message is often allowable, a failure with an error code of WSAEDISCON is used to indicate graceful closure. In any case a return error code of WSAECONNRESET indicates an abortive close has occurred.

The lpFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the lpFlags parameter. The latter is constructed by or-ing any of the following values:

Value | Meaning
MSG_PEEK | Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue. This flag is valid only for nonoverlapped sockets.
MSG_OOB | Process out-of-band data. (See section DECnet Out-Of-band data for a discussion of this topic.)
MSG_PARTIAL | This flag is for message-oriented sockets only. On output, indicates that the data supplied is a portion of the message transmitted by the sender. Remaining portions of the message will be supplied in subsequent receive operations. A subsequent receive operation with MSG_PARTIAL flag cleared indicates end of sender's message. As an input parameter, this flag indicates that the receive operation should complete even if only part of a message has been received by the service provider.

For message-oriented sockets, the MSG_PARTIAL bit is set in the lpFlags parameter if a partial message is received. If a complete message is received, MSG_PARTIAL is cleared in lpFlags. In the case of delayed completion, the value pointed to by lpFlags is not updated. When completion has been indicated, the application should call WSAGetOverlappedResult and examine the flags indicated by the lpdwFlags parameter.

Overlapped socket I/O

If an overlapped operation completes immediately, WSARecv returns a value of zero and the lpNumberOfBytesRecvd parameter is updated with the number of bytes received and the flag bits indicated by the lpFlags parameter are also updated. If the overlapped operation is successfully initiated and will complete later, WSARecv returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd and lpFlags are not updated. When the overlapped operation completes, the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSAGetOverlappedResult. Flag values are obtained by examining the lpdwFlags parameter of WSAGetOverlappedResult.

The WSARecv function can be called from within the completion routine of a previous WSARecv, WSARecvFrom, WSASend or WSASendTo function. For a given socket, I/O completion routines will not be nested. For a given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate WSAOVERLAPPED structure.

If the lpCompletionRoutine parameter is NULL, the hEvent field of lpOverlapped is signaled when the overlapped operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or WSAGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the application to pass context information to the completion routine. A caller that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

The completion routine follows the same rules as stipulated for Win32 file I/O completion routines. The completion routine will not be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents with the fAlertable parameter set to TRUE is invoked.

The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O completion routine, and guarantee that, for a given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The prototype of the completion routine is as follows:

void CALLBACK CompletionROUTINE(
  IN DWORD dwError,
  IN DWORD cbTransferred,
  IN LPWSAOVERLAPPED lpOverlapped,
  IN DWORD dwFlags
);

CompletionRoutine is a placeholder for an application-defined or library-defined function name. The dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred parameter specifies the number of bytes received. The dwFlags parameter contains information that would have appeared in lpFlags if the receive operation had completed immediately. This function does not return a value.

Returning from this function allows invocation of another pending completion routine for this socket. When using WSAWaitForMultipleEvents, all waiting completion routines are called before the alertable thread's wait is satisfied with a return code of WSA_IO_COMPLETION. The completion routines can be called in any order, not necessarily in the same order the overlapped operations are completed. However, the posted buffers are guaranteed to be filled in the same order they are supplied.

Return Values

If no error occurs and the receive operation has completed immediately, WSARecv returns zero. In this case, the completion routine will have already been scheduled to be called once the calling thread is in the alertable state. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that the overlapped operation was not successfully initiated and no completion indication will occur.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOTCONN | The socket is not connected.
WSAEINTR | The (blocking) call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpBuffers parameter is not completely contained in a valid part of the user address space.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to call WSARecv on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.
WSAEWOULDBLOCK | Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is marked as nonblocking and the receive operation cannot be completed immediately.
WSAEMSGSIZE | The message was too large to fit into the specified buffer and (for unreliable protocols only) any trailing portion of the message that did not fit into the buffer has been discarded.
WSAEINVAL | The socket has not been bound (for example, with bind).
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure.
WSAECONNRESET | The virtual circuit was reset by the remote side.
WSAEDISCON | Socket s is message oriented and the virtual circuit was gracefully closed by the remote side.
WSA_IO_PENDING | An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSA_OPERATION_ABORTED | The overlapped operation has been canceled due to the closure of the socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACloseEvent, WSACreateEvent, WSAGetOverlappedResult, WSASocket, WSAWaitForMultipleEvents


WSARecvDisconnect

The Windows Sockets WSARecvDisconnect function terminates reception on a socket, and retrieves the disconnect data if the socket is connection oriented.

int WSARecvDisconnect (
  SOCKET s,
  LPWSABUF lpInboundDisconnectData
);

Parameters

s
[in] A descriptor identifying a socket.
lpInboundDisconnectData
[out] A pointer to the incoming disconnect data.

Remarks

The WSARecvDisconnect function is used on connection-oriented sockets to disable reception and retrieve any incoming disconnect data from the remote party.This is equivalent to a shutdown(SD_RECV), except that WSASendDisconnect also allows receipt of disconnect data (in protocols that support it).

After this function has been successfully issued, subsequent receives on the socket will be disallowed. Calling WSARecvDisconnect has no effect on the lower protocol layers. For TCP sockets, if there is still data queued on the socket waiting to be received, or data arrives subsequently, the connection is reset, since the data cannot be delivered to the user. For UDP, incoming datagrams are accepted and queued. In no case will an ICMP error packet be generated.

To successfully receive incoming disconnect data, an application must use other mechanisms to determine that the circuit has been closed. For example, an application needs to receive an FD_CLOSE notification, to receive a zero return value, or to receive a WSAEDISCON or WSAECONNRESET error code from recv/WSARecv.

The WSARecvDisconnect function does not close the socket, and resources attached to the socket will not be freed until closesocket is invoked.

The WSARecvDisconnect function does not block regardless of the SO_LINGER setting on the socket.

An application should not rely on being able to re-use a socket after it has been disconnected using WSARecvDisconnect. In particular, a Windows Sockets provider is not required to support the use of connect /WSAConnect on such a socket.

Return Values

If no error occurs, WSARecvDisconnect returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The buffer referenced by the parameter lpInboundDisconnectData is too small.
WSAENOPROTOOPT | The disconnect data is not supported by the indicated protocol family.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only).
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

connect, socket


WSARecvEx

Notice This function is a Microsoft-specific extension to the Windows Sockets specification. For more information, see Microsoft Extensions and Windows Sockets 2.

The Windows Sockets WSARecvEx function is identical to the recv function, except the flags parameter is an in-out parameter. When a partial message is received while using datagram protocol, the MSG_PARTIAL bit is set in the flags parameter on return from the function.

int PASCAL FAR WSARecvEx (
  SOCKET s,
  char FAR * buf,
  int len,
  int *flags
);

Parameters

s
[in] A descriptor identifying a connected socket.
buf
[out] A buffer for the incoming data.
len
[in] The length of buf.
flags
[in/out] An indicator specifying whether the message is fully or partially received for datagram sockets.

Remarks

The WSARecvEx function that is part of the Microsoft implementation of Windows Sockets 2 is similar to the more common recv function except that the flags parameter is an in-out parameter, not just an in parameter. The additional out parameter is used to indicate whether a partial or complete message was received when a message-oriented protocol is being used.

The WSARecvEx and recv function identically for stream oriented protocols.

Making the flags parameter an in and out parameter accomodates two common situations in which a partial message will be received: when the application's data buffer size is smaller than the message size and the message coincidentally arrives in two pieces; and when the message is rather large and must arrive in several pieces. The MSG_PARTIAL bit is set in the flags parameter on return from WSARecvEx when a partial message was received. If a complete message was received, MSG_PARTIAL is not set in flags.

The Windows Sockets recv function is different than WSARecvEx in that the recv function always receives a single message for each call for message-oriented transport protocols. The recv function does not have a means to indicate to the application that the data received is only a partial message. An application must build its own protocol for checking whether a message is partial or complete by checking for the error code WSAEMSGSIZE after each call to recv. When the application buffer is smaller than the data being sent, as much of the message as will fit is copied into the user's buffer and recv returns with the error code WSAEMSGSIZE. A subsequent call to recv will get the next part of the message.

Applications written for message-oriented transport protocols should be coded for this possibility if message sizing is not guaranteed by the application's data transfer protocol. An application can use recv and manage the protocol itself. Alternatively, an applications can use WSARecvEx and check the for the MSG_PARTIAL bit is set in the flags parameter.

The WSARecvEx function provide the developer with a more effective way of checking whether a message received is partial or complete when a very large message arrives a little at a time. For example, if an application sends a 1-megabyte message, the transport protocol must break up the message in order to send it over the physical network. It is theoretically possible for the transport protocol on the receiving side to buffer all the data in the message, but this would be quite expensive in terms of resources. Instead, WSARecvEx can be used, minimizing overhead and eliminating the need for an application-based protocol.

Return Values

If no error occurs, WSARecvEx returns the number of bytes received. If the connection has been closed, it returns zero. Additionally, if a partial message was received, the MSG_PARTIAL bit is set in the flags parameter. If a complete message was received, MSG_PARTIAL is not set in flags.

Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Important For a stream oriented transport protocol, MSG_PARTIAL is never set on return from WSARecvEx. This function behaves identically to the Windows Sockets recv function for stream transport protocols.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The buf parameter is not completely contained in a valid part of the user address space.
WSAENOTCONN | The socket is not connected.
WSAEINTR | The (blocking) call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENETRESET | The connection has been broken due to the remote host resetting.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to use WSARecvEx on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the receive operation would block.
WSAEINVAL | The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled or (for byte stream sockets only) len was zero or negative.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.
WSAETIMEDOUT | The connection has been dropped because of a network failure or because the peer system failed to respond.
WSAECONNRESET | The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. The application should close the socket as it is no longer usable. On a UDP datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in mswsock.h.
Import Library: Link with mswsock.lib.

See Also

recvfrom, select, send, socket, WSAAsyncSelect


WSARecvFrom

The Windows Sockets WSARecvFrom function receives a datagram and stores the source address.

int WSARecvFrom (
  SOCKET s,
  LPWSABUF lpBuffers,
  DWORD dwBufferCount,
  LPDWORD lpNumberOfBytesRecvd,
  LPDWORD lpFlags,
  struct sockaddr FAR * lpFrom,
  LPINT lpFromlen,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE
);

Parameters

s
[in] A descriptor identifying a socket
lpBuffers
[in/out] A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length of the buffer.
dwBufferCount
[in] The number of WSABUF structures in the lpBuffers array.
lpNumberOfBytesRecvd
[out] A pointer to the number of bytes received by this call if the receive operation completes immediately.
lpFlags
[in/out] A pointer to flags.
lpFrom
[out] An optional pointer to a buffer that will hold the source address upon the completion of the overlapped operation.
lpFromlen
[in/out] A pointer to the size of the from buffer, required only if lpFrom is specified.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the receive operation has been completed (ignored for nonoverlapped sockets).

Remarks

The WSARecvFrom function provides functionality over and above the standard recvfrom function in three important areas:

  1. It can be used in conjunction with overlapped sockets to perform overlapped receive operations.
  2. It allows multiple receive buffers to be specified making it applicable to the scatter/gather type of I/O.
  3. The lpFlags parameter is both an input and an output parameter, allowing applications to sense the output state of the MSG_PARTIAL flag bit. Note however, that the MSG_PARTIAL flag bit is not supported by all protocols.

The WSARecvFrom functions is used primarily on a connectionless socket specified by s. The socket's local address must be known. For server applications, this is usually done explicitly through bind. Explicit binding is discouraged for client applications. For client applications using this function the socket can become bound implicitly to a local address through sendto, WSASendTo, or WSAJoinLeaf.

For overlapped sockets, this function is used to post one or more buffers into which incoming data will be placed as it becomes available on a (possibly connected) socket, after which the application-specified completion indication (invocation of the completion routine or setting of an event object) occurs. If the operation does not complete immediately, the final completion status is retrieved through the completion routine or WSAGetOverlappedResult. Also, the values indicated by lpFrom and lpFromlen are not updated until completion is itself indicated. Applications must not use or disturb these values until they have been updated, therefore the application must not use automatic (that is, stack-based) variables for these parameters.

If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a nonoverlapped socket.

For nonoverlapped sockets, the blocking semantics are identical to that of the standard WSARecv function and the lpOverlapped and lpCompletionRoutine parameters are ignored. Any data that has already been received and buffered by the transport will be copied into the supplied user buffers. For the case of a blocking socket with no data currently having been received and buffered by the transport, the call will block until data is received.

The supplied buffers are filled in the order in which they appear in the array indicated by lpBuffers, and the buffers are packed so that no holes are created.

The array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation completes in an overlapped manner, it is the service provider's responsibility to capture these WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays.

For connectionless socket types, the address from which the data originated is copied to the buffer indicated by lpFrom. The value pointed to by lpFromlen is initialized to the size of this buffer, and is modified on completion to indicate the actual size of the address stored there. As noted previously for overlapped sockets, the lpFrom and lpFromlen parameters are not updated until after the overlapped I/O has completed. The memory pointed to by these parameters must, therefore, remain available to the service provider and cannot be allocated on the application's stack frame. The lpFrom and lpFromlen parameters are ignored for connection-oriented sockets.

For byte stream-style sockets (for example, type SOCK_STREAM), incoming data is placed into the buffers until the buffers are filled, until the connection is closed, or until the internally buffered data is exhausted. Regardless of whether or not the incoming data fills all the buffers, the completion indication occurs for overlapped sockets. For message-oriented sockets, an incoming message is placed into the supplied buffers up to the total size of the buffers supplied, and the completion indication occurs for overlapped sockets. If the message is larger than the buffers supplied, the buffers are filled with the first part of the message. If the MSG_PARTIAL feature is supported by the underlying service provider, the MSG_PARTIAL flag is set in lpFlags and subsequent receive operation(s) will retrieve the rest of the message. If MSG_PARTIAL is not supported but the protocol is reliable, WSARecvFrom generates the error WSAEMSGSIZE and a subsequent receive operation with a larger buffer can be used to retrieve the entire message. Otherwise, (that is, the protocol is unreliable and does not support MSG_PARTIAL), the excess data is lost, and WSARecvFrom generates the error WSAEMSGSIZE.

The lpFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the lpFlags parameter. The latter is constructed by or-ing any of the following values:

Value | Meaning
MSG_PEEK | Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue. This flag is valid only for nonoverlapped sockets.
MSG_OOB | Process out-of-band data. (See section DECnet Out-Of-band data for a discussion of this topic.)
MSG_PARTIAL | This flag is for message-oriented sockets only. On output, indicates that the data supplied is a portion of the message transmitted by the sender. Remaining portions of the message will be supplied in subsequent receive operations. A subsequent receive operation with MSG_PARTIAL flag cleared indicates end of sender's message. As an input parameter indicates that the receive operation should complete even if only part of a message has been received by the service provider.

For message-oriented sockets, the MSG_PARTIAL bit is set in the lpFlags parameter if a partial message is received. If a complete message is received, MSG_PARTIAL is cleared in lpFlags. In the case of delayed completion, the value pointed to by lpFlags is not updated. When completion has been indicated the application should call WSAGetOverlappedResult and examine the flags pointed to by the lpdwFlags parameter.

Overlapped socket I/O

If an overlapped operation completes immediately, WSARecvFrom returns a value of zero and the lpNumberOfBytesRecvd parameter is updated with the number of bytes received and the flag bits pointed by the lpFlags parameter are also updated. If the overlapped operation is successfully initiated and will complete later, WSARecvFrom returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd and lpFlags is not updated. When the overlapped operation completes the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSAGetOverlappedResult. Flag values are obtained either through the dwFlags parameter of the completion routine, or by examining the lpdwFlags parameter of WSAGetOverlappedResult.

The WSARecvFrom function can be called from within the completion routine of a previous WSARecv, WSARecvFrom, WSASend or WSASendTo function. For a given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate WSAOVERLAPPED structure.

If the lpCompletionRoutine parameter is NULL, the hEvent field of lpOverlapped is signaled when the overlapped operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or WSAGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the application to pass context information to the completion routine. A caller that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

The completion routine follows the same rules as stipulated for Win32 file I/O completion routines. The completion routine will not be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents with the fAlertable parameter set to TRUE is invoked.

The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O completion routine, and guarantee that, for a given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The prototype of the completion routine is as follows:

void CALLBACK CompletionROUTINE(
  IN DWORD dwError,
  IN DWORD cbTransferred,
  IN LPWSAOVERLAPPED lpOverlapped,
  IN DWORD dwFlags
);

The CompletionRoutine is a placeholder for an application-defined or library-defined function name. The dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred specifies the number of bytes received. The dwFlags parameter contains information that would have appeared in lpFlags if the receive operation had completed immediately. This function does not return a value.

Returning from this function allows invocation of another pending completion routine for this socket. When using WSAWaitForMultipleEvents, all waiting completion routines are called before the alertable thread's wait is satisfied with a return code of WSA_IO_COMPLETION. The completion routines can be called in any order, not necessarily in the same order the overlapped operations are completed. However, the posted buffers are guaranteed to be filled in the same order they are supplied.

Return Values

If no error occurs and the receive operation has completed immediately, WSARecvFrom returns zero. In this case, the completion routine will have already been scheduled to be called once the calling thread is in the alertable state. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that the overlapped operation was not successfully initiated and no completion indication will occur.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The lpBuffers, lpFlags, lpFrom, lpNumberOfBytesRecvd, lpFromlen, lpOverlapped, or lpCompletionRoutine argument is not totally contained in a valid part of the user address space: the lpFrom buffer was too small to accommodate the peer address.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | The socket has not been bound (with bind, for example).
WSAEISCONN | The socket is connected. This function is not permitted with a connected socket, whether the socket is connection-oriented or connectionless.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only).
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to WSARecvFrom on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.
WSAEWOULDBLOCK | Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is marked as nonblocking and the receive operation cannot be completed immediately.
WSAEMSGSIZE | The message was too large to fit into the specified buffer and (for unreliable protocols only) any trailing portion of the message that did not fit into the buffer has been discarded.
WSAECONNRESET | The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. The application should close the socket as it is no longer useable. On a UDP datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.
WSAEDISCON | Socket s is message oriented and the virtual circuit was gracefully closed by the remote side.
WSA_IO_PENDING | An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSA_OPERATION_ABORTED | The overlapped operation has been canceled due to the closure of the socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACloseEvent, WSACreateEvent, WSAGetOverlappedResult, WSASocket, WSAWaitForMultipleEvents


WSARemoveServiceClass

The Windows Sockets WSARemoveServiceClass function permanently unregisters service class schema.

INT WSARemoveServiceClass(
  LPGUID lpServiceClassId
);

Parameters

lpServiceClassId
[in] A pointer to the GUID for the service class you want to remove.

Return Values

The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSATYPE_NOT_FOUND | The specified class was not found.
WSAEACCES | The calling routine does not have sufficient privileges to remove the Service.
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
WSAEINVAL | The specified GUID was not valid.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSAResetEvent

The Windows Sockets WSAResetEvent function resets the state of the specified event object to nonsignaled.

BOOL WSAResetEvent(
  WSAEVENT hEvent
);

Parameters

hEvent
[in] A handle that identifies an open event object handle.

Remarks

The WSAResetEvent function is used to set the state of the event object to nonsignaled.

Return Values

If the WSAResetEvent function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSA_INVALID_HANDLE | The hEvent parameter is not a valid event object handle.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACloseEvent, WSACreateEvent, WSASetEvent


WSASend

The Windows Sockets WSASend function sends data on a connected socket.

int WSASend (
  SOCKET s,
  LPWSABUF lpBuffers,
  DWORD dwBufferCount,
  LPDWORD lpNumberOfBytesSent,
  DWORD dwFlags,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE
);

Parameters

s
[in] A descriptor identifying a connected socket.
lpBuffers
[in] A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length of the buffer. This array must remain valid for the duration of the send operation.
dwBufferCount
[in] The number of WSABUF structures in the lpBuffers array.
lpNumberOfBytesSent
[out] A pointer to the number of bytes sent by this call if the I/O operation completes immediately.
dwFlags
[in] A flag that specifies the way in which the call is made.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the send operation has been completed (ignored for nonoverlapped sockets).

Remarks

The WSASend function provides functionality over and above the standard send function in two important areas:

  1. It can be used in conjunction with overlapped sockets to perform overlapped send operations.
  2. It allows multiple send buffers to be specified making it applicable to the scatter/gather type of I/O.

The WSASend function is used to write outgoing data from one or more buffers on a connection-oriented socket specified by s. It can also be used, however, on connectionless sockets that have a stipulated default peer address established through the connect or WSAConnect function.

For overlapped sockets (created using WSASocket with flag WSA_FLAG_OVERLAPPED) sending information uses overlapped I/O, unless both lpOverlapped and lpCompletionRoutine are NULL. In that case, the socket is treated as a nonoverlapped socket. A completion indication will occur, invoking of the completion routine or setting of an event object, when the supplied buffer(s) have been consumed by the transport. If the operation does not complete immediately, the final completion status is retrieved through the completion routine or WSAGetOverlappedResult.

If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a non-overlapped socket.

For nonoverlapped sockets, the last two parameters (lpOverlapped, lpCompletionRoutine) are ignored and WSASend adopts the same blocking semantics as send. Data is copied from the supplied buffer(s) into the transport's buffer. If the socket is nonblocking and stream oriented, and there is not sufficient space in the transport's buffer, WSASend will return with only part of the application's buffers having been consumed. Given the same buffer situation and a blocking socket, WSASend will block until all of the application's buffer contents have been consumed.

The array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation is completed in an overlapped manner, it is the service provider's responsibility to capture these WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays.

For message-oriented sockets, care must be taken not to exceed the maximum message size of the underlying provider, which can be obtained by getting the value of socket option SO_MAX_MSG_SIZE. If the data is too long to pass atomically through the underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.

Note Tthe successful completion of a WSASend does not indicate that the data was successfully delivered.

The dwFlags paramter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter. The latter is constructed by or-ing any of the following values:

Value | Meaning
MSG_DONTROUTE | Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
MSG_OOB | Send out-of-band data on a stream-style socket such as SOCK_STREAM only. (See section DECnet Out-Of-band data for a discussion of this topic.)
MSG_PARTIAL | Specifies that lpBuffers only contains a partial message. Note that the error code WSAEOPNOTSUPP will be returned by transports that do not support partial message transmissions.

Overlapped socket I/O

If an overlapped operation completes immediately, WSASend returns a value of zero and the lpNumberOfBytesSent parameter is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later, WSASend returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent is not updated. When the overlapped operation completes the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSAGetOverlappedResult.

The WSASend function can be called from within the completion routine of a previous WSARecv, WSARecvFrom, WSASend or WSASendTo function. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate WSAOVERLAPPED structure.

If the lpCompletionRoutine parameter is NULL, the hEvent field of lpOverlapped is signaled when the overlapped operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or WSAGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the application to pass context information to the completion routine. A caller that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

The completion routine follows the same rules as stipulated for Win32 file I/O completion routines. The completion routine will not be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents with the fAlertable parameter set to TRUE is invoked.

The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O completion routine, and guarantee that, for a given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The prototype of the completion routine is as follows:

void CALLBACK CompletionROUTINE(
  IN DWORD dwError,
  IN DWORD cbTransferred,
  IN LPWSAOVERLAPPED lpOverlapped,
  IN DWORD dwFlags
);

The CompletionRoutine function is a placeholder for an application-defined or library-defined function name. dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. cbTransferred specifies the number of bytes sent. Currently there are no flag values defined and dwFlags will be zero. This function does not return a value.

Returning from this function allows invocation of another pending completion routine for this socket. All waiting completion routines are called before the alertable thread's wait is satisfied with a return code of WSA_IO_COMPLETION. The completion routines can be called in any order, not necessarily in the same order the overlapped operations are completed. However, the posted buffers are guaranteed to be sent in the same order they are supplied.

Return Values

If no error occurs and the send operation has completed immediately, WSASend returns zero. In this case, the completion routine will have already been scheduled to be called once the calling thread is in the alertable state. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that the overlapped operation was not successfully initiated and no completion indication will occur.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEACCES | The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The lpBuffers, lpNumberOfBytesSent, lpOverlapped, lpCompletionRoutine argument is not totally contained in a valid part of the user address space.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOBUFS | The Windows Sockets provider reports a buffer deadlock.
WSAENOTCONN | The socket is not connected.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, MSG_PARTIAL is not supported, or the socket is unidirectional and supports only receive operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to WSASend on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
WSAEWOULDBLOCK | Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is marked as nonblocking and the send operation cannot be completed immediately.
WSAEMSGSIZE | The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
WSAEINVAL | The socket has not been bound with bind, or the socket is not created with the overlapped flag.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure.
WSAECONNRESET | The virtual circuit was reset by the remote side.
WSA_IO_PENDING | An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSA_OPERATION_ABORTED | The overlapped operation has been canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACloseEvent, WSACreateEvent, WSAGetOverlappedResult, WSASocket, WSAWaitForMultipleEvents


WSASendDisconnect

The Windows Sockets WSASendDisconnect function initiates termination of the connection for the socket and sends disconnect data.

int WSASendDisconnect (
  SOCKET s,
  LPWSABUF lpOUT boundDisconnectData
);

Parameters

s
[in] A descriptor identifying a socket.
lpOutboundDisconnectData
[in] A pointer to the outgoing disconnect data.

Remarks

The WSASendDisconnect functions is used on connection-oriented sockets to disable transmission, and to initiate termination of the connection along with the transmission of disconnect data, if any. This is equivalent to a shutdown(SD_SEND), except that WSASendDisconnect also allows sending disconnect data (in protocols that support it).

After this function has been successfully issued, subsequent sends are disallowed.

The lpOutboundDisconnectData parameter, if not NULL, points to a buffer containing the outgoing disconnect data to be sent to the remote party for retrieval by using WSARecvDisconnect.

The WSASendDisconnect function does not close the socket, and resources attached to the socket will not be freed until closesocket is invoked.

The WSASendDisconnect function does not block regardless of the SO_LINGER setting on the socket.

An application should not rely on being able to re-use a socket after calling WSASendDisconnect. In particular, a Windows Sockets provider is not required to support the use of connect /WSAConnect on such a socket.

Return Values

If no error occurs, WSASendDisconnect returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAENOPROTOOPT | The parameter lpOutboundDisconnectData is not NULL, and the disconnect data is not supported by the service provider.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only).
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpOutboundDisconnectData parameter is not completely contained in a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

connect, socket


WSASendTo

The Windows Sockets WSASendTo function sends data to a specific destination, using overlapped I/O where applicable.

int WSASendTo (
  SOCKET s,
  LPWSABUF lpBuffers,
  DWORD dwBufferCount,
  LPDWORD lpNumberOfBytesSent,
  DWORD dwFlags,
  const struct sockaddr FAR * lpTo,
  int iToLen,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE
);

Parameters

s
[in] A descriptor identifying a (possibly connected) socket.
lpBuffers
[in] A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length of the buffer. This array must remain valid for the duration of the send operation.
dwBufferCount
[in] The number of WSABUF structures in the lpBuffers array.
lpNumberOfBytesSent
[out] A pointer to the number of bytes sent by this call if the I/O operation completes immediately.
dwFlags
[in] An indicator specifying the way in which the call is made.
lpTo
[in] An optional pointer to the address of the target socket.
iToLen
[in] The size of the address in lpTo.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the send operation has been completed (ignored for nonoverlapped sockets).

Remarks

The WSASendTo function provides functionality over and above the standard sendto function in two important areas:

  1. It can be used in conjunction with overlapped sockets to perform overlapped send operations.
  2. It allows multiple send buffers to be specified making it applicable to the scatter/gather type of I/O.

The WSASendTo function is normally used on a connectionless socket specified by s to send a datagram contained in one or more buffers to a specific peer socket identified by the lpTo parameter. Even if the connectionless socket has been previously connected using the connect function to a specific address, lpTo overrides the destination address for that particular datagram only. On a connection-oriented socket, the lpTo and iToLen parameters are ignored; in this case, the WSASendTo is equivalent to WSASend.

For overlapped sockets (created using WSASocket with flag WSA_FLAG_OVERLAPPED) sending data uses overlapped I/O, unless both lpOverlapped and lpCompletionRoutine are NULL in which case the socket is treated as a nonoverlapped socket. A completion indication will occur (invoking the completion routine or setting of an event object) when the supplied buffer(s) have been consumed by the transport. If the operation does not complete immediately, the final completion status is retrieved through the completion routine or WSAGetOverlappedResult.

If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a non-overlapped socket.

For nonoverlapped sockets, the last two parameters (lpOverlapped, lpCompletionRoutine) are ignored and WSASendTo adopts the same blocking semantics as send. Data is copied from the supplied buffer(s) into the transport's buffer. If the socket is nonblocking and stream oriented, and there is not sufficient space in the transport's buffer, WSASendTo returns with only part of the application's buffers having been consumed. Given the same buffer situation and a blocking socket, WSASendTo will block until all of the application's buffer contents have been consumed.

The array of WSABUF structures indicated by the lpBuffers parameter is transient. If this operation is completed in an overlapped manner, it is the sercvice provider's responsibility to capture these WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays.

For message-oriented sockets, care must be taken not to exceed the maximum message size of the underlying transport, which can be obtained by getting the value of socket option SO_MAX_MSG_SIZE. If the data is too long to pass atomically through the underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.

The successful completion of a WSASendTo does not indicate that the data was successfully delivered.

The dwFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter. The latter is constructed by or-ing any of the following values:

Value | Meaning
MSG_DONTROUTE | Specifies that the data should not be subject to routing. A Windows Socket service provider may choose to ignore this flag.
MSG_OOB | Send out-of-band data (stream-style socket such as SOCK_STREAM only).
MSG_PARTIAL | Specifies that lpBuffers only contains a partial message. Note that the error code WSAEOPNOTSUPP will be returned by transports that do not support partial message transmissions.

Overlapped socket I/O

If an overlapped operation completes immediately, WSASendTo returns a value of zero and the lpNumberOfBytesSent parameter is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later, WSASendTo returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent is not updated. When the overlapped operation completes the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSAGetOverlappedResult.

The WSASendTo function can be called from within the completion routine of a previous WSARecv, WSARecvFrom, WSASend or WSASendTo function. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate WSAOVERLAPPED structure.

If the lpCompletionRoutine parameter is NULL, the hEvent field of lpOverlapped is signaled when the overlapped operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or WSAGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the application to pass context information to the completion routine. A caller that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

The completion routine follows the same rules as stipulated for Win32 file I/O completion routines. The completion routine will not be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents with the fAlertable parameter set to TRUE is invoked.

Transport providers allow an application to invoke send and receive operations from within the context of the socket I/O completion routine, and guarantee that, for a given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The prototype of the completion routine is as follows:

void CALLBACK CompletionROUTINE(
  IN DWORD dwError,
  IN DWORD cbTransferred,
  IN LPWSAOVERLAPPED lpOverlapped,
  IN DWORD dwFlags
);

The CompletionRoutine function is a placeholder for an application-defined or library-defined function name. The dwError paramter specifies the completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred parameter specifies the number of bytes sent. Currently there are no flag values defined and dwFlags will be zero. This function does not return a value.

Returning from this function allows invocation of another pending completion routine for this socket. All waiting completion routines are called before the alertable thread's wait is satisfied with a return code of WSA_IO_COMPLETION. The completion routines can be called in any order, not necessarily in the same order the overlapped operations are completed. However, the posted buffers are guaranteed to be sent in the same order they are supplied.

Return Values

If no error occurs and the send operation has completed immediately, WSASendTo returns zero. In this case, the completion routine will have already been scheduled to be called once the calling thread is in the alertable state. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that the overlapped operation was not successfully initiated and no completion indication will occur.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEACCES | The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINTR | A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo argument is too small.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOBUFS | The Windows Sockets provider reports a buffer deadlock.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only)
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, MSG_PARTIAL is not supported, or the socket is unidirectional and supports only receive operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
WSAEWOULDBLOCK | Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is marked as nonblocking and the send operation cannot be completed immediately.
WSAEMSGSIZE | The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
WSAEINVAL | The socket has not been bound with bind, or the socket is not created with the overlapped flag.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure.
WSAECONNRESET | The virtual circuit was reset by the remote side.
WSAEADDRNOTAVAIL | The remote address is not a valid address (such as ADDR_ANY).
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAEDESTADDRREQ | A destination address is required.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSA_IO_PENDING | An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSA_OPERATION_ABORTED | The overlapped operation has been canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACloseEvent, WSACreateEvent, WSAGetOverlappedResult, WSASocket, WSAWaitForMultipleEvents


WSASetBlockingHook

This function has been removed in compliance with the Windows Sockets 2 specification, revision 2.2.0.

The function is not exported directly by the WS2_32.DLL, and Windows Sockets 2 applications should not use this function. Windows Sockets 1.1 applications that call this function are still supported through the WINSOCK.DLL and WSOCK32.DLL.

Blocking hooks are generally used to keep a single-threaded GUI application responsive during calls to blocking functions. Instead of using blocking hooks, an applications should use a separate thread (separate from the main GUI thread) for network activity.

WSAIsBlocking, WSACancelBlockingCall


WSASetEvent

The Windows Sockets WSASetEvent function sets the state of the specified event object to signaled.

BOOL WSASetEvent(
  WSAEVENT hEvent
);

Paramters

hEvent
[in] A handle that identifies an open event object.

Remarks

The WSASetEvent function sets the state of the event object to be signaled.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To get extended error information, call WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSA_INVALID_HANDLE | The hEvent paramter is not a valid event object handle.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACloseEvent, WSACreateEvent, WSAResetEvent


WSASetLastError

The Windows Sockets WSASetLastError function sets the error code that can be retrieved through the WSAGetLastError function.

void WSASetLastError (
  int iError
);

Parameters

iError
[in] An integer that specifies the error code to be returned by a subsequent WSAGetLastError call.

Remarks

The WSASetLastError function allows an application to set the error code to be returned by a subsequent WSAGetLastError call for the current thread. Note that any subsequent Windows Sockets routine called by the application will override the error code as set by this routine.

The error code set by WSASetLastError is different from the error code reset by calling the function getsockopt with SO_ERROR.

Return Values

None.

Error Codes

WSANOTINITIALISED A successful WSAStartup must occur before using this function.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

getsockopt, WSAGetLastError


WSASetService

The Windows Sockets WSASetService function registers or deregisters a service instance within one or more name spaces. This function can be used to affect a specific name space provider, all providers associated with a specific name space, or all providers across all name spaces.

INT WSASetService(
  LPWSAQUERYSET lpqsRegInfo,
  WSAESETSERVICEOP essOperation,
  DWORD dwControlFlags
);

Parameters

lpqsRegInfo
[in] A pointer to the service information for registration or deregistration.
essOperation
[in] An enumeration whose values include:
RNRSERVICE_REGISTER
Register the service. For SAP, this means sending out a periodic broadcast. This is a NOP for the DNS name space. For persistent data stores, this means updating the address information.
RNRSERVICE_DEREGISTER
Deregister the service. For SAP, this means stop sending out the periodic broadcast. This is a NOP for the DNS name space. For persistent data stores this means deleting address information.
RNRSERVICE_DELETE
Delete the service from dynamic name and persistent spaces. For services represented by multiple CSADDR_INFO structures (using the SERVICE_MULTIPLE flag), only the supplied address will be deleted, and this much match exactly the corresponding CSADD_INFO structure that was supplied when the service was registered.
dwControlFlags
[in] The meaning of dwControlFlags is dependent on the following values:
Flag | Meaning
SERVICE MULTIPLE | Controls scope of operation. When clear, service addresses are managed as a group. A register or deregister invalidates all existing addresses before adding the given address set. When set, the action is only performed on the given address set. A register does not invalidate existing addresses and a deregister only invalidates the given set of addresses.

The available values for essOperation and dwControlFlags combine to give meanings as shown in the following table:

Operation | Flags | Service already exists | Service does not exist
RNRSERVICE _REGISTER | none | Overwrite the object. Use only addresses specified. Object is REGISTERED. | Create a new object. Use only addresses specified. Object is REGISTERED.
RNRSERVICE _REGISTER | SERVICE _MULTIPLE | Update object. Add new addresses to existing set. Object is REGISTERED. | Create a new object. Use all addresses specified. Object is REGISTERED.
RNRSERVICE _DEREGISTER | none | Remove all addresses, but do not remove object from name space. Object is DEREGISTERED. | WSASERVICE _NOT_FOUND
RNRSERVICE _DEREGISTER | SERVICE _MULTIPLE | Update object. Remove only addresses that are specified. Only mark object as DEREGISTERED if no addresses present. Do not remove from the name space. | WSASERVICE _NOT_FOUND
RNRSERVICE _DELETE | none | Remove object from the name space. | WSASERVICE _NOT_FOUND
RNRSERVICE _DELETE | SERVICE _MULTIPLE | Remove only addresses that are specified. Only remove object from the name space if no addresses remain. | WSASERVICE _NOT_FOUND

Remarks

SERVICE_MULTIPLE lets an application manage its addresses independently. This is useful when the application wants to manage its protocols individually or when the service resides on more than one machine. For instance, when a service uses more than one protocol, it may find that one listening socket aborts but the others remain operational. In this case, the service could deregister the aborted address without affecting the other addresses.

When using SERVICE_MULTIPLE, an application must not let stale addresses remain in the object. This can happen if the application aborts without issuing a DEREGISTER request. When a service registers, it should store its addresses. On its next invocation, the service should explicitly deregister these old stale addresses before registering new addresses.

Service Properties

The following table describes how service property data is represented in a WSAQUERYSET structure. Fields labeled as (Optional) can be supplied with a NULL pointer.

WSAQUERYSET Field Name | Service Property Description
Field Name | Service Property Description
dwSize | Must be set to sizeof(WSAQUERYSET). This is a versioning mechanism.
DwOutputFlags | Not applicable and ignored.
LpszServiceInstanceName | Referenced string contains the service instance name.
LpServiceClassId | The GUID corresponding to this service class.
lpVersion | (Optional) Supplies service instance version number.
LpszComment | (Optional) An optional comment string.
DwNameSpace | See table below.
LpNSProviderId | See table below.
LpszContext | (Optional) Specifies the starting point of the query in a hierarchical name space.
DwNumberOfProtocols | Ignored.
LpafpProtocols | Ignored.
LpszQueryString | Ignored.
DwNumberOfCsAddrs | The number of elements in the array of CSADDRO_INFO structures referenced by lpcsaBuffer.
LpcsaBuffer | A pointer to an array of CSADDRO_INFO structures that contain the address(es) that the service is listening on.
lpBlob | (Optional) This is a pointer to a provider-specific entity.

As illustrated below, the combination of the dwNameSpace and lpNSProviderId parameters determine that name space providers are affected by this function.

dwNameSpace | lpNSProviderId | Scope of Impact
Ignored | Non-NULL | The specified name space provider
a valid name space ID | NULL | All name space providers that support the indicated name space
NS_ALL | NULL | All name space providers

Return Values

The return value for WSASetService is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSAEACCES | The calling routine does not have sufficient privileges to install the Service.
WSAEINVAL | One or more required parameters were invalid or missing.
WSANOTINITIALIZED | The WiS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.
WSASERVICE NOT FOUND | No such service is known. The service cannot be found in the specified name space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSASocket

The Windows Sockets WSASocket function creates a socket that is bound to a specific transport service provider, and optionally creates and/or joins a socket group.

SOCKET WSASocket (
  int af,
  int type,
  int protocol,
  LPWSAPROTOCOL_INFO lpProtocolInfo,
  GROUP g,
  DWORD dwFlags
);

Parameters

af
[in] An address family specification.
type
[in] A type specification for the new socket.
protocol
[in] A particular protocol to be used with the socket that is specific to the indicated address family.
lpProtocolInfo
[in] A pointer to a WSAPROTOCOL_INFO structure that defines the characteristics of the socket to be created.
g
[in] Reserved for future use with socket groups. The identifier of the socket group.
dwFlags
[in] A flag that specifies the socket attribute.

Remarks

The WSASocket function causes a socket descriptor and any related resources to be allocated and associated with a transport service provider. By default, the socket will not have an overlapped attribute. If lpProtocolInfo is NULL, the WS2_32.DLL uses the first three parameters (af, type, protocol) to determine which service provider is used by selecting the first transport provider able to support the stipulated address family, socket type and protocol values. If the lpProtocolInfo is not NULL, the socket will be bound to the provider associated with the indicated WSAPROTOCOL_INFO structure. In this instance, the application can supply the manifest constant FROM_PROTOCOL_INFO as the value for any of af, type or protocol. This indicates that the corresponding values from the indicated WSAPROTOCOL_INFO structure (iAddressFamily, iSocketType, iProtocol) are to be assumed. In any case, the values supplied for af, type and protocol are supplied unmodified to the transport service provider.

When selecting a protocol and its supporting service provider based on af, type and protocol, this procedure will only choose a base protocol or a protocol chain, not a protocol layer by itself. Unchained protocol layers are not considered to have "partial matches" on type or af either. That is, they do not lead to an error code of WSAEAFNOSUPPORT or WSAEPROTONOSUPPORT if no suitable protocol is found.

Note The manifest constant AF_UNSPEC continues to be defined in the header file but its use is strongly discouraged, as this can cause ambiguity in interpreting the value of the protocol parameter.

Reserved for future use with socket groups. Parameter g is used to indicate the appropriate actions on socket groups:

  1. If g is an existing socket group ID, join the new socket to this group, provided all the requirements set by this group are met; or
  2. If g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket group and have the new socket be the first member; or
  3. If g = SG_CONSTRAINED_GROUP, create a constrained socket group and have the new socket be the first member; or
  4. If g = zero, no group operation is performed.

For unconstrained groups, any set of sockets can be grouped together as long as they are supported by a single service provider. A constrained socket group can consist only of connection-oriented sockets, and requires that connections on all grouped sockets be to the same address on the same host. For newly created socket groups, the new group ID can be retrieved by using getsockopt with option SO_GROUP_ID, if this operation completes successfully. A socket group and its associated ID remain valid until the last socket belonging to this socket group is closed. Socket group IDs are unique across all processes for a given service provider.

The dwFlags parameter can be used to specify the attributes of the socket by or-ing any of the following Flags:

Flag | Meaning
WSA_FLAG_OVERLAPPED | This flag causes an overlapped socket to be created. Overlapped sockets can utilize WSASend, WSASendTo, WSARecv, WSARecvFrom and WSAIoctl for overlapped I/O operations, which allows multiple these operations to be initiated and in progress simultaneously. All functions that allow overlapped operation (WSASend, WSARecv,WSASendTo, WSARecvFrom, WSAIoctl) also support non-overlapped usage on an overlapped socket if the values for parameters related to overlapped operation are NULL.
WSA_FLAG_MULTIPOINT_C_ROOT | Indicates that the socket created will be a c_root in a multipoint session. Only allowed if a rooted control plane is indicated in the protocol's WSAPROTOCOL_INFO structure. Refer to Multipoint and Multicast Semantics for additional information.
WSA_FLAG_MULTIPOINT_C_LEAF | Indicates that the socket created will be a c_leaf in a multicast session. Only allowed if XP1_SUPPORT_MULTIPOINT is indicated in the protocol's WSAPROTOCOL_INFO structure. Refer to Multipoint and Multicast Semantics for additional information.
WSA_FLAG_MULTIPOINT_D_ROOT | Indicates that the socket created will be a d_root in a multipoint session. Only allowed if a rooted data plane is indicated in the protocol's WSAPROTOCOL_INFO structure. Refer to Multipoint and Multicast Semantics for additional information.
WSA_FLAG_MULTIPOINT_D_LEAF | Indicates that the socket created will be a d_leaf in a multipoint session. Only allowed if XP1_SUPPORT_MULTIPOINT is indicated in the protocol's WSAPROTOCOL_INFO structure. Refer to Multipoint and Multicast Semantics for additional information.

Important For multipoint sockets, exactly one of WSA_FLAG_MULTIPOINT_C_ROOT or WSA_FLAG_MULTIPOINT_C_LEAF must be specified, and exactly one of WSA_FLAG_MULTIPOINT_D_ROOT or WSA_FLAG_MULTIPOINT_D_LEAF must be specified. Refer to Multipoint and Multicast Semantics for additional information.

Connection-oriented sockets such as SOCK_STREAM provide full-duplex connections, and must be in a connected state before any data can be sent or received on them. A connection to another socket is created with a connect/WSAConnect call. Once connected, data can be transferred using send/WSASend and recv/WSARecv calls. When a session has been completed, a closesocket must be performed.

The communications protocols used to implement a reliable, connection-oriented socket ensure that data is not lost or duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT.

Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using sendto /WSASendTo and recvfrom /WSARecvFrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer using send/WSASend and can be received from (only) this peer using recv/WSARecv.

Support for sockets with type RAW is not required, but service providers are encourages to support raw sockets whenever it makes sense to do so.

Shared Sockets
When a special WSAPROTOCOL_INFO structure (obtained through the WSADuplicateSocket function and used to create additional descriptors for a shared socket) is passed as an input parameter to WSASocket, the g and dwFlags parameters are ignored. Such a WSAPROTOCOL_INFO struct may only be used once, otherwise the error code WSAEINVAL will result.

Return Values

If no error occurs, WSASocket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEAFNOSUPPORT | The specified address family is not supported.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEMFILE | No more socket descriptors are available.
WSAENOBUFS | No buffer space is available. The socket cannot be created.
WSAEPROTONOSUPPORT | The specified protocol is not supported.
WSAEPROTOTYPE | The specified protocol is the wrong type for this socket.
WSAESOCKTNOSUPPORT | The specified socket type is not supported in this address family.
WSAEINVAL | The parameter g specified is not valid, or the WSAPROTOCOL_INFO structure that lpProtocolInfo points to is incomplete, the contents are invalid or the WSAPROTOCOL_INFO structurehas already been used in an earlier duplicate socket operation.
WSAEFAULT | lpProtocolInfo argument is not in a valid part of the process address space.
WSAINVALIDPROVIDER | The service provider returned a version other than 2.2.
WSAINVALIDPROCTABLE | The service provider returned an invalid or incomplete procedure table to the WSPStartup.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

accept, bind, connect, getsockname, getsockopt, ioctlsocket, listen, recv, recvfrom, select, send, sendto, setsockopt, shutdown


WSAStartup

The Windows Sockets WSAStartup function initiates use of WS2_32.DLL by a process.

int WSAStartup (
  WORD wVersionRequested,
  LPWSADATA lpWSAData
);

Parameters

wVersionRequested
[in] The highest version of Windows Sockets support that the caller can use. The high order byte specifies the minor version (revision) number; the low-order byte specifies the major version number.
lpWSAData
[out] A pointer to the WSADATA data structure that is to receive details of the Windows Sockets implementation.

Remarks

The WSAStartup function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets required and to retrieve details of the specific Windows Sockets implementation. The application or DLL can only issue further Windows Sockets functions after a successfully calling WSAStartup.

In order to support future Windows Sockets implementations and applications that can have functionality differences from current version of Windows Sockets, a negotiation takes place in WSAStartup. The caller of WSAStartup and the WS2_32.DLL indicate to each other the highest version that they can support, and each confirms that the other's highest version is acceptable. Upon entry to WSAStartup, the WS2_32.DLL examines the version requested by the application. If this version is equal to or higher than the lowest version supported by the DLL, the call succeeds and the DLL returns in wHighVersion the highest version it supports and in wVersion the minimum of its high version and wVersionRequested. The WS2_32.DLL then assumes that the application will use wVersion. If the wVersion field of the WSADATA structure is unacceptable to the caller, it should call WSACleanup and either search for another WS2_32.DLL or fail to initialize.

It is legal and possible for an application written to this version of the specification to successfully negotiate a higher version number than the version of this specification. In such a case, the application is only guaranteed access to higher-version functionality that fits within the syntax defined in this version, such as new Ioctl codes and new behavior of existing functions. New functions, for example, may be inaccessible. To be guaranteed full access to new syntax of a future version, the application must fully conform to that future version, such as compiling against a new header file, linking to a new library, or other special cases.

This negotiation allows both a WS2_32.DLL and a Windows Sockets application to support a range of Windows Sockets versions. An application can use WS2_32.DLL if there is any overlap in the version ranges. The following chart gives examples of how WSAStartup works in conjunction with different application and WS2_32.DLL versions:

App versions | DLL Versions | wVersion Requested | wVersion | wHigh Version | End Result
1.1 | 1.1 | 1.1 | 1.1 | 1.1 | use 1.1
1.0 1.1 | 1.0 | 1.1 | 1.0 | 1.0 | use 1.0
1.0 | 1.0 1.1 | 1.0 | 1.0 | 1.1 | use 1.0
1.1 | 1.0 1.1 | 1.1 | 1.1 | 1.1 | use 1.1
1.1 | 1.0 | 1.1 | 1.0 | 1.0 | Application fails
1.0 | 1.1 | 1.0 | --- | --- | WSAVERNOT SUPPORTED
1.0 1.1 | 1.0 1.1 | 1.1 | 1.1 | 1.1 | use 1.1
1.1 2.0 | 1.1 | 2.0 | 1.1 | 1.1 | use 1.1
2.0 | 2.0 | 2.0 | 2.0 | 2.0 | use 2.0

The following code fragment demonstrates how an application that supports only version 2.2 of Windows Sockets makes a WSAStartup call:

WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
    /* Tell the user that we could not find a usable */
    /* WinSock DLL.                                  */
    return;
}

/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater    */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we      */
/* requested.                                        */

if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 2 ) {
    /* Tell the user that we could not find a usable */
    /* WinSock DLL.                                  */
    WSACleanup( );
    return;
}

/* The WinSock DLL is acceptable. Proceed. */

Once an application or DLL has made a successful WSAStartup call, it can proceed to make other Windows Sockets calls as needed. When it has finished using the services of the WS2_32.DLL, the application or DLL must call WSACleanup in order to allow the WS2_32.DLL to free any resources for the application.

Details of the actual Windows Sockets implementation are described in the WSADATA structure.

An application or DLL can call WSAStartup more than once if it needs to obtain the WSAData structure information more than once. On each such call the application can specify any version number supported by the DLL.

An application must call one WSACleanup call for every successful WSAStartup call to allow third-party DLLs to make use of a WS2_32.DLL on behalf of an application. This means, for example, that if an application calls WSAStartup three times, it must call WSACleanup three times. The first two calls to WSACleanup do nothing except decrement an internal counter; the final WSACleanup call for the task does all necessary resource deallocation for the task.

Return Values

The WSAStartup function returns zero if successful. Otherwise, it returns one of the error codes listed below.

An application cannot call WSAGetLastError to determine the error code as is normally done in Windows Sockets is WSAStartup fails. The WS2_32.DLL will not have been loaded in the case of a failure so the client data area where the "last error" information is stored could not be established.

Error Codes

WSASYSNOTREADY | Indicates that the underlying network subsystem is not ready for network communication.
WSAVERNOTSUPPORTED | The version of Windows Sockets support requested is not provided by this particular Windows Sockets implementation.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 operation is in progress.
WSAEPROCLIM | Limit on the number of tasks supported by the Windows Sockets implementation has been reached.
WSAEFAULT | The lpWSAData is not a valid pointer.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

send, sendto, WSACleanup


WSAStringToAddress

The Windows Sockets WSAStringToAddress function converts a numeric string to a SOCKADDR structure, suitable for passing to Windows Sockets routines that take such a structure.

INT WSAStringToAddress(
  LPTSTR AddressString,
  INT AddressFamily,
  LPWSAPROTOCOL_INFO lpProtocolInfo,
  LPSOCKADDR lpAddress,
  LPINT lpAddressLength
);

Parameters

AddressString
[in] Points to the zero-terminated human-readable numeric string to convert.
AddressFamily
[in] The address family to which the string belongs.
lpProtocolInfo
[in] (optional) the WSAPROTOCOL_INFO structureassociated with the provider to be used. If this is NULL, the call is routed to the provider of the first protocol supporting the indicated AddressFamily.
Address
[out] A buffer that is filled with a single SOCKADDR.
lpAddressLength
[in/out] The length of the Address buffer. Returns the size of the resultant SOCKADDR structure. If the supplied buffer is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated with the required size in bytes.

Remarks

The WSAStringToAddress function converts alpha-numeric address to SOCKADDR structures. WSAStringToAddress is the protocol independent equivalent of the BSD inet_ntoa function.

Any missing components of the address will be defaulted to a reasonable value, if possible. For example, a missing port number will default to zero. If the caller wants the translation to be done by a particular provider, it should supply the corresponding WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.

Return Values

The return value for WSAStringToAddress is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.

Error Codes

WSAEFAULT | The specified Address buffer is too small. Pass in a larger buffer.
WSAEINVAL | Unable to translate the string into a SOCKADDR.
WSANOTINITIALIZED | The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Socket functions.
WSA NOT ENOUGH MEMORY | There was insufficient memory to perform the operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.


WSAUnhookBlockingHook

This function has been removed in compliance with the Windows Sockets 2 specification, revision 2.2.0.

The function is not exported directly by the WS2_32.DLL, and Windows Sockets 2 applications should not use this function. Windows Sockets 1.1 applications that call this function are still supported through the WINSOCK.DLL and WSOCK32.DLL.

Blocking hooks are generally used to keep a single-threaded GUI application responsive during calls to blocking functions. Instead of using blocking hooks, an applications should use a separate thread (separate from the main GUI thread) for network activity.


WSAWaitForMultipleEvents

The Windows Sockets WSAWaitForMultipleEvents function returns either when one or all of the specified event objects are in the signaled state, or when the time-out interval expires.

DWORD WSAWaitForMultipleEvents(
  DWORD cEvents,
  const WSAEVENT FAR *lphEvents,
  BOOL fWaitAll,
  DWORD dwTimeOUT,
  BOOL fAlertable
);

Parameters

cEvents
[in] An indicator specifying the number of event object handles in the array pointed to by lphEvents. The maximum number of event object handles is WSA_MAXIMUM_WAIT_EVENTS. One or more events must be specified.
lphEvents
[in] A pointer to an array of event object handles.
fWaitAll
[in] An indicator specifying the wait type. If TRUE, the function returns when all event objects in the lphEvents array are signaled at the same time. If FALSE, the function returns when any one of the event objects is signaled. In the latter case, the return value indicates the event object whose state caused the function to return.
dwTimeout
[in] An indicator specifying the time-out interval, in milliseconds. The function returns if the interval expires, even if conditions specified by the fWaitAll parameter are not satisfied. If dwTimeout is zero, the function tests the state of the specified event objects and returns immediately. If dwTimeout is WSA_INFINITE, the function's time-out interval never expires.
fAlertable
[in] An indicator specifying whether the function returns when the system queues an I/O completion routine for execution by the calling thread. If TRUE, the completion routine is executed and the function returns. If FALSE, the completion routine is not executed when the function returns.

Remarks

The WSAWaitForMultipleEvents function returns either when any one or when all of the specified objects are in the signaled state, or when the time-out interval elapses. This function is also used to perform an alertable wait by setting the parameter fAltertable to be TRUE. This enables the function to return when the system queues an I/O completion routine to be executed by the calling thread.

When fWaitAll is TRUE, the function's wait condition is satisfied only when the state of all objects is signaled at the same time. The function does not modify the state of the specified objects until all objects are simultaneously signaled.

Applications that simply need to enter an alertable wait state without waiting for any event objects to be signalled should use the Win32 SleepEx function.

Return Values

If the WSAWaitForMultipleEvents function succeeds, the return value indicates the event object that caused the function to return.

If the function fails, the return value is WSA_WAIT_FAILED. To get extended error information, call WSAGetLastError.

The return value upon success is one of the following values:

Value | Meaning
WSA_WAIT_EVENT_0 to (WSA_WAIT_EVENT_0 + cEvents - 1) | If fWaitAll is TRUE, the return value indicates that the state of all specified event objects is signaled. If fWaitAll is FALSE, the return value minus WSA_WAIT_EVENT_0 indicates the lphEvents array index of the object that satisfied the wait.
WAIT_IO_COMPLETION | One or more I/O completion routines are queued for execution.
WSA_WAIT_TIMEOUT | The time-out interval elapsed and the conditions specified by the fWaitAll parameter are not satisfied.

Error Codes

WSANOTINITIALISED | A successful WSAStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to complete the operation.
WSA_INVALID_HANDLE | One or more of the values in the lphEvents array is not a valid event object handle.
WSA_INVALID_PARAMETER | The cEvents parameter does not contain a valid handle count.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also

WSACloseEvent, WSACreateEvent


AFPROTOCOLS

typedef struct _AFPROTOCOLS {
    INT iAddressFamily;
    INT iProtocol;
} AFPROTOCOLS, *PAFPROTOCOLS, *LPAFPROTOCOLS;


BLOB

A BLOB structure contains information about a block of data.

typedef struct _BLOB {
    ULONG   cbSize;
    BYTE    *pBlobData;
} BLOB;

Members

cbSize
Specifies the size in bytes of the block of data pointed to by pBlobData
Addresses
Points to a block of data.

Remarks

The structure name BLOB comes from the acronym BLOB, which stands for "Binary Large OBject".

Note that this structure description says nothing about the nature of the data pointed to by pBlobData.

QuickInfo

Windows CE: Unsupported.
Header: Declared in wtypes.h.

See Also

SERVICE_INFO


CSADDR_INFO

The CSADDR_INFO structure contains Windows Sockets address information for a network service or name space provider. The GetAddressByName function obtains Windows Sockets address information using CSADDR_INFO structures.

typedef struct _CSADDR_INFO {
    SOCKET_ADDRESS  LocalAddr;
    SOCKET_ADDRESS  RemoteAddr;
    INT             iSocketType;
    INT             iProtocol;
} CSADDR_INFO;

Members

LocalAddr
Specifies a Windows Sockets local address.

In a client application, pass this address to the bind function to obtain access to a network service.

In a network service, pass this address to the bind function so that the service is bound to the appropriate local address.

RemoteAddr
Specifies a Windows Sockets remote address. There are several uses for this remote address:
  • You can use this remote address to connect to the service via the connect function. This is useful if an application performs send/receive operations that involve connection-oriented protocols.
  • You can use this remote address with the sendto function when you are communicating over a connectionless (datagram) protocol. If you are using a connectionless protocol, such as UDP, sendto is typically the way you pass data to the remote system.
iSocketType
Specifies the type of the Windows socket. The following socket types are defined in WINSOCK.H:
Value | Socket Type
SOCK_STREAM | Stream.This is a protocol that sends data as a stream of bytes, with no message boundaries.
SOCK_DGRAM | Datagram. This is a connectionless protocol. There is no virtual circuit setup. There are typically no reliability guarantees. Services use recvfrom to obtain datagrams. The listen and accept functions do not work with datagrams.
SOCK_RDM | Reliably-Delivered Message. This is a protocol that preserves message boundaries in data.
SOCK_SEQPACKET | Sequenced packet stream. This is a protocol that is essentially the same as SOCK_RDM.

iProtocol
Specifies a value to pass as the protocol parameter to the socket function to open a socket for this service.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.

See Also

bind, connect, GetAddressByName, recv, send, sendto


FD_SET

typedef struct fd_set {
        u_int fd_count;                 /* how many are SET? */
        SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */
} fd_set;

Element | Usage
fd_count | The number of sockets that are set.
fd_array | An array of the sockets in the set.


FLOWSPEC

typedef struct _flowspec {
    uint32        TokenRate;            /* In Bytes/sec    */
    uint32        TokenBucketSize;      /* In Bytes        */
    uint32        PeakBandwidth;        /* In Bytes/sec    */
    uint32        Latency;              /* In microseconds */
    uint32        DelayVariation;       /* In microseconds */
    SERVICETYPE   ServiceType;          /* Guaranteed, Predictive, */
                                        /* Best Effort, etc.  */
   uint32         MaxSduSize            /* In Bytes           */
   uint32         MinimumPolicedSize    /* In Bytes           */
} FLOWSPEC, *PFLOWSPEC,  FAR * LPFLOWSPEC;

typedef struc _QualityOfService {
    FLOWSPECSendingFlowspec/*The flowspec for data sending*/
    FLOWSPECReceivingFlowspec/*Theflowspec for data receiving*/
    WSABUFProviderSpecific/*Additonal Provider*/
} QOS, FAR * LPQOS;

Members

TokenRate
A token bucket model is used to specify the rate at which permission to send traffic (or credits) accrues. In the model, the token bucket has a maximum volume (TokenBucketSize) and continuously fills at a certain rate, (TokenRate). If the bucket contains sufficient credit, the application can send data and reduce the available credit by that amount. If sufficient credits are not available, the application must wait or discard the extra traffic.

A value of -1 in the members TokenRate and TokenBucketSize indicates that no rate-limiting is in force. The TokenRate is expressed in bytes per second.

If an application has been sending at a low rate for a period of time, it can send a large burst of data all at once until it runs out of credit. Having done so, it must limit itself to sending at TokenRate until its data burst is exhausted.

In video applications, the TokenRate is typically the average bit rate peak to peak. In constant rate applications, the TokenRate is equal to the PeakBandwidth.

TokenBucketSize
Largest typical frame size in video applications, expressed in bytes. In constant rate applications, the TokenBucketSize is chosen to accommodate small variations.
PeakBandwidth
Limits how fast packets may be sent back to back from the application, expressed in bytes/second. Some intermediate systems can take advantage of this information resulting in a more efficient resource allocation.
Latency
Maximum acceptable delay between transmission of a bit by the sender and its receipt by the intended receiver or receivers, expressed in microseconds. The precise interpretation of this number depends on the level of guarantee specified in the QOS request.
DelayVariation
Difference, in microseconds, between the maximum and minimum possible delay that a packet will experience. This value is used by applications to determine the amount of buffer space needed at the receiving side in order to restore the original data transmission pattern.
ServiceType
Contains the value of the level of service to negotiate for the flow. The following ServiceTypes have been defined.
SERVICETYPE_NOTRAFFIC
In either the sending or receiving flow specification, this value indicates that there will be no traffic in this direction. On duplex capable media, this signals underlying software to set up unidirectional connections only.
SERVICETYPE_BESTEFFORT
The service provider takes the FLOWSPEC as a guideline and makes reasonable efforts to maintain the level of service requested, without making any guarantees on packet delivery.
SERVICETYPE_CONTROLLEDLOAD
Denotes that end-to-end behavior, provided to an application by a series of network elements, tightly approximates the behavior visible to applications receiving best-effort service "under unloaded conditions" from the same series of network elements. Thus, applications using this service may assume that: (1) A very high percentage of transmitted packets will be successfully delivered by the network to the receiving end notes. (Packet loss rate will closely approximate the basic packet error rate of the transmission medium.) and (2) Transit delay experienced by a very high percentage of the delivered packets will not greatly exceed the minimum transit delay experienced by any successfully delivered packet at the speed of light.
SERVICETYPE_GUARANTEED
The service provider implements a queuing algorithm which isolates the flow from the effects of other flows as much as possible and guarantees the flow the ability to propagate data at the TokenRate for the duration of the connection. If the sender sends faster than the TokenRate, the network may delay or discard the excess traffic. If the sender does not exceed the TokenRate over time, then Latency is also guaranteed. This ServiceType is designed for applications that require a precisely known quality of service but world not benefit from better service, such as real-time control systems.
SERVICETYPE_NETWORK UNAVAILABLE
In either sending or receiving flow specifications, this value may be used by a service provider to indicate a loss of service in the corresponding direction.
SERVICETYPE_GENERAL_INFORMATION
All service types are supported for this traffic flow.
SERVICETYPE_NOCHANGE
In either sending or receiving flow specifications, this level of service requests that the quality of service in the corresponding direction is not changed. ServiceType_NoChange can be used when requesting a QOS change in one direction only, or when requesting a change only in the ProvderSpecific part of a QOS specification and not in the SendingFlowspec or the ReceivingFlowspec.
SERVICETYPE_IMMEDIATE_TRAFFIC_CONROL
In either a Sending or Receiving flowspec, this may be combined using bit-wise OR with one of the other defined ServiceType values to request the service provider to activate traffic control coincident with provision of the FLOWSPEC.
MaxSduSize
The maximum packet size, in bytes, that is permitted or used in the traffic flow.
MinimumPolicedSize
The minimum packet size that will be given the level of service requested.


GUARANTEE

typedef enum {
    BestEffortService,
    ControlledLoadService,
    PredictiveService,
    GuaranteedService
} GUARANTEE;

Types

GuaranteedService
A service provider supporting guaranteed service implements a queuing algorithm which isolates the flow from the effects of other flows as much as possible, and guarantees the flow the ability to propagate data at the TokenRate for the duration of the connection. If the sender sends faster than that rate, the network may delay or discard the excess traffic. If the sender does not exceed TokenRate over time, then latency is also guaranteed. This service is designed for applications which require a precisely known quality of service but would not benefit from better service, such as real-time control systems.
PredictiveService
A service provider supporting predictive service guarantees the flow the ability to propagate data at the TokenRate for the duration of the connection. If the sender sends faster than that rate, the network may delay or discard the excess traffic. The delay limit is not guaranteed (occasional packets may take longer than specified), but is generally highly reliable. This service is designed for applications that can accommodate or adapt to some variation in service quality, such as video service.
ControlledLoadService
With this service, end-to-end behavior provided to an application by a series of network elements tightly approximates the behavior visible to applications receiving best-effort service "under unloaded conditions" from the same series of network elements. Thus, applications using this service can assume that:
  1. A very high percentage of transmitted packets will be successfully delivered by the network to the receiving end-nodes. (Packet loss rate will closely approximate the basic packet error rate of the transmission medium).
  2. Transit delay experienced by a very high percentage of the delivered packets will not greatly exceed the minimum transit delay experienced by any successfully delivered packet at the speed of light.

    Note This definition comes from the Internet Engineering Task Force (IETF).

BestEffortService
A service provider supporting best effort service, at minimum, takes the flow spec as a guideline and makes reasonable efforts to maintain the level of service requested, however without making any guarantees whatsoever.


HOSTENT

Windows Sockets allocates this structure is allocated. An application should never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, and so the application should copy any information that it needs before issuing any other Windows Sockets API calls.

struct hostent {
    char FAR *       h_name;
    char FAR * FAR * h_aliases;
    short            h_addrtype;
    short            h_length;
    char FAR * FAR * h_addr_list;
};

Members

h_name
Official name of the host (PC).If using the DNS or similar resolution system, it is the Fully Qualified Domain Name (FQDN) that caused the server to return a reply. If using a local "hosts" file, it is the first entry after the IP address.
h_aliases
A NULL-terminated array of alternate names.
h_addrtype
The type of address being returned.
h_length
The length, in bytes, of each address.
h_addr_list
A NULL-terminated list of addresses for the host. Addresses are returned in network byte order. The macro h_addr is defined to be h_addr_list[0] for compatibility with older software.


IN_ADDR

struct in_addr {
        union {
                struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
                struct { u_short s_w1,s_w2; } S_un_w;
                u_long S_addr;
        } S_un;


LINGER

struct linger {
    u_short    l_onoff;
    u_short    l_linger;
}

Members

l_onoff
To enable SO_LINGER, the application should set l_onoff to a nonzero value, set l_linger to zero or the desired time-out (in seconds), and call setsockopt. To enable SO_DONTLINGER (that is, disable SO_LINGER) l_onoff should be set to zero and setsockopt should be called. Note that enabling SO_LINGER with a nonzero time-out on a nonblocking socket is not recommended.

Enabling SO_LINGER also disables SO_DONTLINGER, and vice versa. Note that if SO_DONTLINGER is DISABLED (that is, SO_LINGER is ENABLED) then no time-out value is specified. In this case, the time-out used is implementation dependent. If a previous time-out has been established for a socket (by enabling SO_LINGER), then this time-out value should be reinstated by the service provider.


NS_SERVICE_INFO

The NS_SERVICE_INFO structure contains information about a network service or a network service type in the context of a specified name space, or a set of default name spaces.

typedef struct _NS_SERVICE_INFO {
    DWORD   dwNameSpace;
    SERVICE_INFO ServiceInfo;
} NS_SERVICE_INFO;

Members

dwNameSpace
Specifies the name space or a set of default name spaces to which this service information applies.

Use one of the following constant values to specify a name space:
Value | Name Space
NS_DEFAULT | A set of default name spaces. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set.
NS_DNS | The Domain Name System used in the Internet to resolve the name of the host.
NS_MS
NS_NDS | The NetWare 4 provider.
NS_NETBT | The NetBIOS over TCP/IP layer. The operating system registers their computer names with NetBIOS. This name space is used to convert a computer name to an IP address that uses this registration.
NS_NIS
NS_SAP | The NetWare Service Advertising Protocol. This can access the Netware bindery, if appropriate. NS_SAP is a dynamic name space that enables the registration of services.
NS_STDA
NS_TCPIP_HOSTS | Lookup value in the <systemroot>\system32\drivers\etc\posts file.
NS_TCPIP_LOCAL | Local TCP/IP name resolution mechanisms, including comparisons against the local host name and lookup value in the cache of host to IP address mappings.
NS_WINS
NS_X500

ServiceInfo
A SERVICE_INFO structure that contains information about a network service or network service type.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.

See Also

SERVICE_INFO


PROTOCOL_INFO

The PROTOCOL_INFO structure contains information about a protocol.

typedef  struct _PROTOCOL_INFO {
    DWORD  dwServiceFlags;
    INT  iAddressFamily;
    INT  iMaxSockAddr;
    INT  iMinSockAddr;
    INT  iSocketType;
    INT  iProtocol;
    DWORD  dwMessageSize;
    LPTSTR  lpProtocol;
} PROTOCOL_INFO;

Members

dwServiceFlags
A set of bit flags that specify the services provided by the protocol. One or more of the following bit flags may be set:
Value | Meaning
XP_CONNECTIONLESS | If this flag is set, the protocol providesconnectionless (datagram) service. If this flag is clear, the protocol provides connection-oriented data transfer.
XP_GUARANTEED_DELIVERY | If this flag is set, the protocol guarantees that all data sent will reach the intended destination. If this flag is clear, there is no such guarantee.
XP_GUARANTEED_ORDER | If this flag is set, the protocol guarantees that data will arrive in the order in which it was sent. Note that this characteristic does not guarantee delivery of the data, but guarantees only its order. If this flag is clear, the order of data sent is not guaranteed.
XP_MESSAGE_ORIENTED | If this flag is set, the protocol is message-oriented. A message-oriented protocol honors message boundaries. If this flag is clear, the protocol is stream-oriented, and the concept of message boundaries is irrelevant.
XP_PSEUDO_STREAM If this flag is set, the protocol is a message-oriented protocol that ignores message boundaries for all receive operations.

This optional capability is useful when you do not want the protocol to frame messages. An application that requires stream-oriented characteristics can open a socket with type SOCK_STREAM for transport protocols that support this functionality, regardless of the value of iSocketType.
XP_GRACEFUL_CLOSE | If this flag is set, the protocol supports two-phase close operations, also known as "graceful" close operations. If this flag is clear, the protocol supports only abortive close operations.
XP_EXPEDITED_DATA | If this flag is set, the protocol supports expedited data, also known as "urgent data."
XP_CONNECT_DATA | If this flag is set, the protocol supports connect data.
XP_DISCONNECT_DATA | If this flag is set, the protocol supports disconnect data.
XP_SUPPORTS_BROADCAST | If this flag is set, the protocol supports a broadcast mechanism.
XP_SUPPORTS_MULTICAST | If this flag is set, the protocol supports a multicast mechanism.
XP_BANDWIDTH_ALLOCATION | If this flag is set, the protocol supports a mechanism for allocating a guaranteed bandwidth to an application.
XP_FRAGMENTATION | If this flag isset, the protocol supports message fragmentation; physical network MTU is hidden from applications.
XP_ENCRYPTS | If this flag is set, the protocol supports data encryption.

iAddressFamily
Specifies the value to pass as the af parameter when you call the socket function to open a socket for the protocol. This address family value uniquely defines the structure of Protocol addresses, also known as SOCKADDRs, used by the protocol.
iMaxSockAddr
Specifies the maximum length of a socket address supported by the protocol.
iMinSockAddr
Specifies the minimum length of a socket address supported by the protocol.
iSocketType
Specifies the value to pass as the type parameter when you call the socket function to open a socket for the protocol.

Note that if XP_PSEUDO_STREAM is set in dwServiceFlags, the application can specify SOCK_STREAM as the type parameter to socket, regardless of the value of iSocketType.

iProtocol
Specifies the value to pass as the protocol parameter when you call the socket function to open a socket for the protocol.
dwMessageSize
Specifies the maximum message size supported by the protocol. This is the maximum size of a message that can be sent from or received by the host. For protocols that do not support message framing, the actual maximum size of a message that can be sent to a given address may be less than this value.

The following special message size values are defined:
Value | Meaning
0 | The protocol is stream-oriented; the concept of message size is not relevant.
0xFFFFFFFF | The protocol is message-oriented, but there is no maximum message size.

lpProtocol
Points to a zero-terminated string that supplies a name for the protocol; for example, "SPX2."

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.

See Also

EnumProtocols, socket


PROTOENT

struct protoent {
    char FAR *        p_name;
    char FAR * FAR *  p_aliases;
    short             p_proto;
};

The members of this structure are:

Element | Usage
p_name | Official name of the protocol.
P_aliases | A NULL-terminated array of alternate names.
P_proto | The protocol number, in host byte order.

The returned pointer points to a structure that is allocated by the Windows Sockets library. The application must never attempt to modify this structure or to free any of its components. Furthermore only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other Windows Sockets function calls.


QUALITYOFSERVICE

The Windows Sockets 2 QOS structure is defined in WINSOCK2.H and is reproduced here.

typedef struct _QualityOfService {
    FLOWSPEC    SendingFlowspec;       /* The flowspec for data  */
                                       /*   sending              */
    FLOWSPEC    ReceivingFlowspec;     /* The flowspec for data  */
                                       /*   receiving            */
    WSABUF      ProviderSpecific;      /* Additional provider-   */
                                       /*   specific parameters  */
} QOS, FAR * LPQOS;


SERVENT

struct servent {
    char FAR *        s_name;
    char FAR * FAR *  s_aliases;
    short             s_port;
    char FAR *        s_proto;
};

The members of this structure are:

Element | Usage
s_name | Official name of the service.
s_aliases | A NULL-terminated array of alternate names.
s_port | The port number at which the service can be contacted. Port numbers are returned in network byte order.
s_proto | The name of the protocol to use when contacting the service.


SERVICE_ADDRESS

The SERVICE_ADDRESS structure contains address information for a service. The structure can accomodate many types of interprocess communications (IPC) mechanisms and their address forms, including remote procedure calls (RPCs), named pipes, and sockets.

typedef struct _SERVICE_ADDRESS {
    DWORD   dwAddressType;
    DWORD   dwAddressFlags;
    DWORD   dwAddressLength;
    DWORD   dwPrincipalLength;
    BYTE   *lpAddress;
    BYTE   *lpPrincipal;
} SERVICE_ADDRESS;

Members

dwAddressType
Specifies the address family that the socket address pointed to by lpAddress belongs to.
dwAddressFlags
A set of bit flags that specify properties of the address. The following bit flags are defined:
Value Meaning
SERVICE_ADDRESS
_FLAG_RPC_CN 		If this bit flag is set, the service supports connection-oriented RPC over this transport protocol.
SERVICE_ADDRESS
_FLAG_RPC_DG 		If this bit flag is set, the service supports datagram-oriented RPC over this transport protocol.
SERVICE_ADDRESS
_FLAG_RPC_NB 		If this bit flag is set, the service supports NetBIOS RPC over this transport protocol.

dwAddressLength
Specifies the size, in bytes, of the address.
dwPrincipalLength
This member is reserved for future use. It must be zero.
lpAddress
Points to a socket address of the appropriate type.
lpPrincipal
This member is reserved for future use. It must be NULL.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.

See Also

SERVICE_ADDRESSES, SERVICE_INFO


SERVICE_ADDRESSES

The SERVICE_ADDRESSES structure contains an array of SERVICE_ADDRESS data structures.

typedef struct _SERVICE_ADDRESSES {
    DWORD   dwAddressCount;
    SERVICE_ADDRESS   Addresses[1];
} SERVICE_ADDRESSES;

Members

dwAddressCount
Specifies the number of SERVICE_ADDRESS structures in the Addresses array.
Addresses
An array of SERVICE_ADDRESS data structures. Each SERVICE_ADDRESS structure contains information about a network service address.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.

See Also

SERVICE_ADDRESS, SERVICE_INFO


SERVICE_INFO

The SERVICE_INFO structure contains information about a network service or a network service type.

typedef struct _SERVICE_INFO {
    LPGUID   lpServiceType;
    LPTSTR   lpServiceName;
    LPTSTR   lpComment;
    LPTSTR   lpLocale;
    DWORD    dwDisplayHint;
    DWORD    dwVersion;
    DWORD    dwTime;
    LPTSTR   lpMachineName;
    LPSERVICE_ADDRESSES lpServiceAddress;
    BLOB ServiceSpecificInfo;
} SERVICE_INFO;

Members

lpServiceType
Points to a GUID that is the type of the network service.
lpServiceName
Points to a zero-terminated string that is the name of the network service.

If you are calling the SetService function with the dwNameSpace parameter set to NS_DEFAULT, the network service name must be a common name. A common name is what the network service is commonly known as. An example of a common name for a network service is "My SQL Server".

If you are calling the SetService function with the dwNameSpace parameter set to a specific service name, the network service name can be a common name or a distinguished name. A distinguished name distinguishes the service to a unique location with a directory service. An example of a distinguished name for a network service is "MS\\SYS\\NT\\DEV\\My SQL Server".

lpComment
Points to a zero-terminated string that is a comment or description for the network service. For example, "Used for development upgrades."
lpLocale
Points to a zero-terminated string that contains locale information.
dwDisplayHint
Specifies a hint as to how to display the network service in a network browsing user interface. This can be one of the following values:
Value | Meaning
RESOURCEDISPLAYTYPE_DOMAIN | Display the network service as a domain.
RESOURCEDISPLAYTYPE_FILE | Display the network service as a file.
RESOURCEDISPLAYTYPE_GENERIC | The method used to display the object does not matter.
RESOURCEDISPLAYTYPE_GROUP | Display the network service as a group.
RESOURCEDISPLAYTYPE_SERVER | Display the network service as a server.
RESOURCEDISPLAYTYPE_SHARE | Display the network service as a sharepoint.
RESOURCEDISPLAYTYPE_TREE | Display the network service as a tree.

dwVersion
Specifies version information for the network service. The high word of this value specifies a major version number. The low word of this value specifies a minor version number.
dwTime
This member is reserved for future use. It must be set to zero.
lpMachineName
Points to a zero-terminated string that is the name of the computer on which the network service is running.
lpServiceAddress
Points to a SERVICE_ADDRESSES structure that contains an array of SERVICE_ADDRESS structures. Each SERVICE_ADDRESS structure contains information about a network service address.

A network service can call the getsockname function to determine the local address of the system.

ServiceSpecificInfo
A BLOB structure that specifies service-defined information.

Note that, in general, the data pointed to by the BLOB structure's pBlobData member must not contain any pointers. That is because only the network service knows the format of the data; copying the data without such knowledge would lead to pointer invalidation. If the data pointed to by pBlobData contains variable-sized elements, offsets from pBlobData can be used to indicate the location of those elements. There is one exception to this general rule: when pBlobData points to a SERVICE_TYPE_INFO_ABS structure. This is possible because both the SERVICE_TYPE_INFO_ABS structure, and any SERVICE_TYPE_VALUE_ABS structures it contains are predefined, and thus their formats are known to the operating system.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.

See Also

BLOB, GetService, NS_SERVICE_INFO, SetService, SERVICE_ADDRESS, SERVICE_ADDRESSES, SERVICE_TYPE_INFO_ABS, SERVICE_TYPE_VALUE_ABS


SERVICE_TYPE_INFO_ABS

The SERVICE_TYPE_INFO_ABS structure contains information about a network service type. You use a SERVICE_TYPE_INFO_ABS structure to add a network service type to a name space.

typedef struct _SERVICE_TYPE_INFO_ABS {
    LPTSTR                  lpTypeName;
    DWORD                   dwValueCount;
    SERVICE_TYPE_VALUE_ABS  Values[1];
} SERVICE_TYPE_INFO_ABS

Members

lpTypeName
Points to a zero-terminated string that is the name of the network service type. This name is the same in all name spaces, and is used by the GetTypeByName and GetNameByType functions.
dwValueCount
Specifies the number of SERVICE_TYPE_VALUE_ABS structures in the Values member array that follows dwValueCount.
Values[1]
An array of SERVICE_TYPE_VALUE_ABS structures.

Each of these structures contains information about a service type value that the operating system or network service may need when an instance of this network service type is registered with a name space.

The information in these structures may be specific to a name-space. For example, if a network service uses the SAP name space, but does not have a GUID that contains the SAP identifier (SAPID), it defines the SAPID in a SERVICE_TYPE_VALUE_ABS structure.

Remarks

When you use the SetService function to add a network service type to a name space, the SERVICE_TYPE_INFO_ABS structure is passed as the ServiceSpecificInfo BLOB member of a SERVICE_INFO structure. Although the ServiceSpecificInfo member generally should not contain pointers, an exception is made in the case of the SERVICE_TYPE_INFO_ABS and SERVICE_TYPE_VALUE_ABS structures.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.

See Also

SetService, SERVICE_INFO, SERVICE_TYPE_VALUE_ABS


SERVICE_TYPE_VALUE_ABS

The SERVICE_TYPE_VALUE_ABS structure contains information about a network-service type value. This information may be specific to a name space.

typedef struct _SERVICE_TYPE_VALUE_ABS {
    DWORD   dwNameSpace;
    DWORD   dwValueType;
    DWORD   dwValueSize;
    LPTSTR  lpValueName;
    PVOID   lpValue;
} SERVICE_TYPE_VALUE_ABS

Members

dwNameSpace
Specifies the name space, or a set of default name spaces, for which the network service type value is intended. Name-space providers will look only at values intended for their name space.

Use one of the following constants to specify a name space:
Value | Name Space
NS_DEFAULT | A set of default name spaces. The function queries each name space within this set. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set. NS_DEFAULT is the value that most applications should use for dwNameSpace.
NS_DNS | The Domain Name System used in the Internet for host name resolution.
NS_NETBT | The NetBIOS over TCP/IP layer. All Windows NT systems register their computer names with NetBIOS. This name space is used to convert a computer name to an IP address that uses this registration. Note that NS_NETBT may access a WINS server to perform the resolution.
NS_SAP | The Netware Service Advertising Protocol. This may access the Netware bindery if appropriate. NS_SAP is a dynamic name space that allows registration of services.
NS_TCPIP_HOSTS | Lookup value in the <systemroot>\system32\drivers\etc\hosts file.
NS_TCPIP_LOCAL | Local TCP/IP name resolution mechanisms, including comparisons against the local host name and looks up host names and IP addresses in cache of host to IP address mappings.

dwValueType
Specifies the type of the value data. You can specify one of the following types:
Value | Meaning
REG_BINARY | Binary data in any form.
REG_DWORD | A 32-bit number.
REG_MULTI_SZ | An array of null-terminated strings, terminated by two null characters.
REG_SZ | A null-terminated string.

dwValueSize
Specifies the size, in bytes, of the value data. In the case of REG_SZ and REG_MULTI_SZ string data, the terminating characters are counted as part of the size.
lpValueName
Points to a zero-terminated string that is the name of the value. This name is specific to a name space.

Several commonly used value name strings are associated with defined constants. These name strings include the following:
Constant | Name String
SERVICE_TYPE_VALUE_SAPID | "SapId"
SERVICE_TYPE_VALUE_CONN | "ConnectionOriented"
SERVICE_TYPE_VALUE_TCPPORT | "TcpPort"
SERVICE_TYPE_VALUE_UDPPORT | "UdpPort"

lpValue
Points to the value data.

Remarks

When you use the SetService function to add a network service type to a name space, a SERVICE_TYPE_INFO_ABS structure is passed as the ServiceSpecificInfo BLOB member of a SERVICE_INFO structure. Although the ServiceSpecificInfo member generally should not contain pointers, an exception is made in the case of the SERVICE_TYPE_INFO_ABS and SERVICE_TYPE_VALUE_ABS structures.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in nspapi.h.

See Also

SetService, SERVICE_INFO, SERVICE_TYPE_INFO_ABS


SOCKADDR

The SOCKADDR structure varies depending on the protocol selected. Except for the sa_family field, SOCKADDR contents are expressed in network byte order.

struct sockaddr {
        u_short    sa_family;
        char       sa_data[14];
};

In Windows Sockets 2, the name parameter is not strictly interpreted as a pointer to a SOCKADDR structure. It is presented in this manner for Windows Sockets compatibility. The actual structure is interpreted differently in the context of different address families. The only requirements are that the first u_short is the address family and the total size of the memory buffer in bytes is namelen

The structure below is used with TCP/IP. Other protocols use similar structures.

struct sockaddr_in {
        short   sin_family;
        u_short sin_port;
        struct  in_addr sin_addr;
        char    sin_zero[8];
};


SOCKET_ADDRESS

typedef struct _SOCKET_ADDRESS {
    LPSOCKADDR lpSockaddr ;
    INT iSockaddrLength ;
} SOCKET_ADDRESS, *PSOCKET_ADDRESS, FAR * LPSOCKET_ADDRESS ;


TIMEVAL

struct timeval {
        long    tv_sec;         /* seconds */
        long    tv_usec;        /* and microseconds */
};

This structure is used in the select function. It is taken from the BSD file sys/time.h.


TRANSMIT_FILE_BUFFERS

The TRANSMIT_FILE_BUFFERS structure specifies data to be transmitted before and after file data during a TransmitFile function file transfer operation.

typedef struct _TRANSMIT_FILE_BUFFERS {
    PVOID Head;
    DWORD HeadLength;
    PVOID Tail;
    DWORD TailLength;
} TRANSMIT_FILE_BUFFERS;

Members

Head
Pointer to a buffer that contains data to be transmitted before the file data is transmitted.
HeadLength
Specifies the number of bytes of data in the buffer pointed to by the Head member that are to be transmitted.
Tail
Pointer to a buffer that contains data to be transmitted after the file data is transmitted.
TailLength
Specifies the number of bytes of data in the buffer pointed to by the Tail member that are to be transmitted.

QuickInfo

Windows NT: Yes
Windows CE: Unsupported.
Header: Declared in winsock.h.

See Also

TransmitFile


WSABUF

typedef struct __WSABUF {
    u_longlen;     // buffer length
    char FAR *buf; // pointer to buffer
} WSABUF, FAR * LPWSABUF;

Members

len
The length of the buffer.
buf
A pointer to the buffer.


WSADATA

typedef struct WSAData {
        WORD                    wVersion;
        WORD                    wHighVersion;
        char                    szDescription[WSADESCRIPTION_LEN+1];
        char                    szSystemStatus[WSASYS_STATUS_LEN+1];
        unsigned short          iMaxSockets;
        unsigned short          iMaxUdpDg;
        char FAR *              lpVendorInfo;
} WSADATA, FAR * LPWSADATA;

The members of this structure are:

Parameters

wVersion
The version of the Windows Sockets specification that the WS2_32.DLL expects the caller to use.
wHighVersion
The highest version of the Windows Sockets specification that this DLL can support (also encoded as above). Normally this will be the same as wVersion.
szDescription
A null-terminated ASCII string into which the WS2_32.DLL copies a description of the Windows Sockets implementation. The text (up to 256 characters in length) can contain any characters except control and formatting characters: the most likely use that an application will put this to is to display it (possibly truncated) in a status message.
szSystemStatus
A null-terminated ASCII string into which the WS2_32.DLL copies relevant status or configuration information. The WS2_32.DLL should use this field only if the information might be useful to the user or support staff: it should not be considered as an extension of the szDescription field.
iMaxSockets
This field is retained for backward compatibility, but should be ignored for version 2 and later as no single value can be appropriate for all underlying service providers.
iMaxUdpDg
This value should be ignored for version 2 and onward. It is retained for compatibility with Windows Sockets specification 1.1, but should not be used when developing new applications. For the actual maximum message size specific to a particular Windows Sockets service provider and socket type, applications should use getsockopt to retrieve the value of option SO_MAX_MSG_SIZE after a socket has been created.
lpVendorInfo
This value should be ignored for version 2 and onward. It is retained for compatibility with Windows Sockets specification 1.1. Applications needing to access vendor-specific configuration information should use getsockopt to retrieve the value of option PVD_CONFIG. The definition of this value (if utilized) is beyond the scope of this specification.

Note An application should ignore the iMaxsockets, iMaxUdpDg, and lpVendorInfo fields in WSAData if the value in wVersion after a successful call to WSAStartup is at least 2. This is because the architecture of Windows Sockets has been changed in version 2 to support multiple providers, and WSAData no longer applies to a single vendor's stack. Two new socket options are introduced to supply provider-specific information: SO_MAX_MSG_SIZE (replaces the iMaxUdpDg element) and PVD_CONFIG (allows any other provider-specific configuration to occur).


WSAEcomparator

typedef enum _WSAEcomparator {
    COMP_EQUAL = 0,
    COMP_NOTLESS
} WSAECOMPARATOR, *PWSAECOMPARATOR, *LPWSAECOMPARATOR;


WSANAMESPACE_INFO

The WSANAMESPACE_INFO structure contains all of the registration information for a name space provider.

typedef struct _WSANAMESPACE_INFOW {
    GUID                NSProviderId;
    DWORD               dwNameSpace;
    BOOL                fActive;
    DWORD               dwVersion;
    LPWSTR              lpszIdentifier;
} WSANAMESPACE_INFOW, *PWSANAMESPACE_INFOW, *LPWSANAMESPACE_INFOW;

Members

NSProviderId
The unique identifier for this name space provider.
dwNameSpace
Specifies the name space supported by this implementation of the provider.
fActive
If TRUE, indicates that this provider is active. If FALSE, the provider is inactive and is not accessible for queries, even if the query specifically references this provider.
dwVersion
Name Space version identifier.
lpszIdentifier
Display string for the provider.


WSANETWORKEVENTS

typedef struct _WSANETWORKEVENTS {
   long lNetworkEvents;
   int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;

Parameters

lNetworkEvents
A value that indicates which of the FD_XXX network events have occurred.
iErrorCodes
An array that contains any associated error codes, with an array index that corresponds to the position of event bits in lNetworkEvents. The identifiers FD_READ_BIT, FD_WRITE_BIT and other can be used to index the iErrorCodes array.


WSAOVERLAPPED

The WSAOVERLAPPED structure provides a communication medium between the initiation of an overlapped I/O operation and its subsequent completion. The WSAOVERLAPPED structure is designed to be compatible with the Win32 OVERLAPPED structure:

typedef struct _WSAOVERLAPPED {
    DWORD        Internal;
    DWORD        InternalHigh;
    DWORD        Offset;
    DWORD        OffsetHigh;
    WSAEVENT     hEvent;
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;

Members

Internal
This reserved field is used internally by the entity that implements overlapped I/O. For service providers that create sockets as installable file system (IFS) handles, this field is used by the underlying operating system. Other service providers (non-IFS providers) are free to use this field as necessary.
InternalHigh
Reserved field is used internally by the entity that implements overlapped I/O. For service providers that create sockets as IFS handles, this field is used by the underlying operating system. Non-IFS providers are free to use this field as necessary.
OffsetT
This field is reserved for service providers to use.
OffsetHigh
This field is reserved for service providers to use.
Event
If an overlapped I/O operation is issued without an I/O completion routine (lpCompletionRoutine is NULL), then this field should either contain a valid handle to a WSAEVENT object or be NULL. If lpCompletionRoutine is non-NULL then applications are free to use this field as necessary.


WSAPROTOCOL_INFO

typedef struct _WSAPROTOCOL_INFOW {
    DWORD dwServiceFlags1;
    DWORD dwServiceFlags2;
    DWORD dwServiceFlags3;
    DWORD dwServiceFlags4;
    DWORD dwProviderFlags;
    GUID ProviderId;
    DWORD dwCatalogEntryId;
    WSAPROTOCOLCHAIN ProtocolChain;
    int iVersion;
    int iAddressFamily;
    int iMaxSockAddr;
    int iMinSockAddr;
    int iSocketType;
    int iProtocol;
    int iProtocolMaxOffset;
    int iNetworkByteOrder;
    int iSecurityScheme;
    DWORD dwMessageSize;
    DWORD dwProviderReserved;
    WCHAR szProtocol[WSAPROTOCOL_LEN+1];
} WSAPROTOCOL_INFOW, FAR * LPWSAPROTOCOL_INFOW;

Members

dwServiceFlags1
A bitmask describing the services provided by the protocol. The following values are possible:
XP1_CONNECTIONLESS
The protocol provides connectionless (datagram) service. If not set, the protocol supports connection-oriented data transfer.
XP1_GUARANTEED_DELIVERY
The protocol guarantees that all data sent will reach the intended destination.
XP1_GUARANTEED_ORDER
The protocol guarantees that data will only arrive in the order in which it was sent and that it will not be duplicated. This characteristic does not necessarily mean that the data will always be delivered, but that any data that is delivered is delivered in the order in which it was sent.
XP1_MESSAGE_ORIENTED
The protocol honors message boundaries, as opposed to a stream-oriented protocol where there is no concept of message boundaries.
XP1_PSEUDO_STREAM
This is a message oriented protocol, but message boundaries will be ignored for all receives. This is convenient when an application does not desire message framing to be done by the protocol.
XP1_GRACEFUL_CLOSE
The protocol supports two-phase (graceful) close. If not set, only abortive closes are performed.
XP1_EXPEDITED_DATA
The protocol supports expedited (urgent) data.
XP1_CONNECT_DATA
The protocol supports connect data.
XP1_DISCONNECT_DATA
The protocol supports disconnect data.
XP1_INTERRUPT
This bit is reserved.
XP1_SUPPORT_BROADCAST
The protocol supports a broadcast mechanism.
XP1_SUPPORT_MULTIPOINT
The protocol supports a multipoint or multicast mechanism. Control and data plane attributes are indicated below.
XP1_MULTIPOINT_CONTROL_PLANE
Indicates whether the control plane is rooted (value = 1) or non-rooted (value = 0).
XP1_MULTIPOINT_DATA_PLANE
Indicates whether the data plane is rooted (value = 1) or non-rooted (value = 0).
XP1_QOS_SUPPORTED
The protocol supports quality of service requests.
XP1_UNI_SEND
The protocol is unidirectional in the send direction.
XP1_UNI_RECV
the protocol is unidirectional in the recv direction.
XP1_IFS_HANDLES
The socket descriptors returned by the provider are operating system Installable File System (IFS) handles.
XP1_PARTIAL_MESSAGE
The MSG_PARTIAL flag is supported in WSASend and WSASendTo.

Note that only one of XP1_UNI_SEND or XP1_UNI_RECV may be set. If a protocol can be unidirectional in either direction, two WSAPROTOCOL_INFOW structures should be used. When neither bit is set, the protocol is considered to be bi-directional.

dwServiceFlags2
Reserved for additional protocol attribute definitions.
dwServiceFlags3
Reserved for additional protocol attribute definitions.
dwServiceFlags4
Reserved for additional protocol attribute definitions.
dwProviderFlags
Provide information about how this protocol is represented in the protocol catalog. The following flag values are possible:
PFL_MULTIPLE_PROTO_ENTRIES
Indicates that this is one of two or more entries for a single protocol (from a given provider) which is capable of implementing multiple behaviors. An example of this is SPX which, on the receiving side, can behave either as a message oriented or a stream oriented protocol.
PFL_RECOMMENDED_PROTO_ENTRY
Indicates that this is the recommended or most frequently used entry for a protocol which is capable of implementing multiple behaviors.
PFL_HIDDEN
Set by a provider to indicate to the WS2_32.DLL that this protocol should not be returned in the result buffer generated by WSAEnumProtocols. Obviously, a Windows Sockets 2 application should never see an entry with this bit set.
PFL_MATCHES_PROTOCOL_ZERO
Indicates that a value of zero in the protocol parameter of socket or WSASocket matches this protocol entry.
ProviderId
A globally unique identifier assigned to the provider by the service provider vendor. This value is useful for instances where more than one service provider is able to implement a particular protocol. An application may use the dwProviderId value to distinguish between providers that might otherwise be indistinguishable.
dwCatalogEntryId
A unique identifier assigned by the WS2_32.DLL for each WSAPROTOCOL_INFOW structure.

WSAPROTOCOLCHAIN ProtocolChain;

If the length of the chain is 0, this WSAPROTOCOL_INFOW entry represents a layered protocol which has Windows Sockets 2 SPI as both its top and bottom edges. If the length of the chain equals 1, this entry represents a base protocol whose Catalog Entry ID is in the dwCatalogEntryId field of the WSAPROTOCOL_INFOW structure. If the length of the chain is larger than 1, this entry represents a protocol chain which consists of one or more layered protocols on top of a base protocol. The corresponding Catalog Entry IDs are in the ProtocolChain.ChainEntries array starting with the layered protocol at the top (the zero element in the ProtocolChain.ChainEntries array) and ending with the base protocol. Refer to the Windows Sockets 2 Service Provider Interface specification for more information on protocol chains.

iVersion
Protocol version identifier.
iAddressFamily
The value to pass as the address family parameter to the socket/WSASocket function in order to open a socket for this protocol. This value also uniquely defines the structure of protocol addresses (SOCKADDRs) used by the protocol.
iMaxSockAddr
The maximum address length.
iMinSockAddr
The minimum address length.
iSocketType
The value to pass as the socket type parameter to the socket function in order to open a socket for this protocol.
iProtocol
The value to pass as the protocol parameter to the socket function in order to open a socket for this protocol.
iProtocolMaxOffset
The maximum value that may be added to iProtocol when supplying a value for the protocol parameter to socket and WSASocket. Not all protocols allow a range of values. When this is the case iProtocolMaxOffset will be zero.
iNetworkByteOrder
Currently these values are manifest constants (BIGENDIAN and LITTLEENDIAN) that indicate either "big-endian" or "little-endian" with the values 0 and 1 respectively.
iSecurityScheme
Indicates the type of security scheme employed (if any). A value of SECURITY_PROTOCOL_NONE is used for protocols that do not incorporate security provisions.
dwMessageSize
The maximum message size supported by the protocol. This is the maximum size that can be sent from any of the host's local interfaces. For protocols which do not support message framing, the actual maximum that can be sent to a given address may be less. There is no standard provision to determine the maximum inbound message size. The following special values are defined:
0
The protocol is stream-oriented and hence the concept of message size is not relevant.
0x1
The maximum outbound (send) message size is dependent on the underlying network MTU (maximum sized transmission unit) and hence cannot be known until after a socket is bound. Applications should use getsockopt to retrieve the value of SO_MAX_MSG_SIZE after the socket has been bound to a local address.
0xFFFFFFFF
The protocol is message-oriented, but there is no maximum limit to the size of messages that may be transmitted.
dwProviderReserved
Reserved for use by service providers.
szProtocol
An array of characters that contains a human-readable name identifying the protocol, for example "SPX2". The maximum number of characters allowed is WSAPROTOCOL_LEN, which is defined to be 255.


WSAPROTOCOLCHAIN

A structure containing a counted list of Catalog Entry IDs which comprise a protocol chain. This structure is defined as follows:

typedef struct _WSAPROTOCOLCHAIN {
    int ChainLen;           /* the length of the chain,  */
                            /* length = 0 means layered protocol, */
                            /* length = 1 means base protocol,
                            /* length > 1 means protocol chain */
    DWORD ChainEntries[MAX_PROTOCOL_CHAIN];
                            /* a list of dwCatalogEntryIds */
} WSAPROTOCOLCHAIN, FAR * LPWSAPROTOCOLCHAIN;


WSAQuerySet

typedef struct _WSAQuerySetW {
    DWORD           dwSize;
    LPWSTR          lpszServiceInstanceName;
    LPGUID          lpServiceClassId;
    LPWSAVERSION    lpVersion;
    LPWSTR          lpszComment;
    DWORD           dwNameSpace;
    LPGUID          lpNSProviderId;
    LPWSTR          lpszContext;
    DWORD           dwNumberOfProtocols;
    LPAFPROTOCOLS   lpafpProtocols;
    LPWSTR          lpszQueryString;
    DWORD           dwNumberOfCsAddrs;
    LPCSADDR_INFO   lpcsaBuffer;
    DWORD           dwOutputFlags;
    LPBLOB          lpBlob;
} WSAQUERYSETW, *PWSAQUERYSETW, *LPWSAQUERYSETW;

Parameters

dwSize
Must be set to sizeof(WSAQUERYSET). This is a versioning mechanism.
dwOutputflags
Ignored for queries.
lpszServiceInstanceName
(Optional) Referenced string contains service name. The semantics for wildcarding within the string are not defined, but can be supported by certain name space providers.
lpServiceClassId
(Required) The GUID corresponding to the service class.
lpVersion
(Optional) References desired version number and provides version comparison semantics (that is, version must match exactly, or version must be not less than the value supplied).
lpszComment
Ignored for queries.
dwNameSpace1
Identifier of a single name space in which to constrain the search, or NS_ALL to include all name spaces.
lpNSProviderId
(Optional) References the GUID of a specific name space provider, and limits the query to this provider only.
lpszContext
(Optional) Specifies the starting point of the query in a hierarchical name space.
dwNumberOfProtocols
Size of the protocol constraint array, can be zero.
lpafpProtocols
(Optional) References an array of AFPROTOCOLS structure. Only services that utilize these protocols will be returned.
lpszQueryString
(Optional) Some namespaces (such as whois++) support enriched SQL like queries that are contained in a simple text string. This parameter is used to specify that string.
dwNumberOfCsAddrs
Ignored for queries.
lpcsaBuffer
Ignored for queries.
lpBlob
(Optional) This is a pointer to a provider-specific entity.

1 See the Important note below

Important In most instances, applications interested in only a particular transport protocol should constrain their query by address family and protocol rather than by name space. This would allow an application that needs to locate a TCP/IP service, for example, to have its query processed by all available name spaces such as the local hosts file, DNS, and NIS.


WSAServiceClassInfo

typedef struct _WSAServiceClassInfoW {
    LPGUID              lpServiceClassId;
    LPWSTR              lpszServiceClassName;
    DWORD               dwCount;
    LPWSANSCLASSINFOW   lpClassInfos;
} WSASERVICECLASSINFOW, *PWSASERVICECLASSINFOW, *LPWSASERVICECLASSINFOW;


WSATHREADID

typedef struct _WSATHREADID {
    HANDLE ThreadHandle;
    DWORD Reserved;
} WSATHREADID, FAR * LPWSATHREADID;


Legal Information

Windows Sockets 2 Service Provider Interface

This is a preliminary document and may be changed substantially prior to final commercial release. This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document. Information in this document is subject to change without notice. The entire risk of the use or the results of the use of this document remains with the user. The names of companies, products, people, characters, and/or data mentioned herein are fictitious and are in no way intended to represent any real individual, company, product, or event, unless otherwise noted. Complying with all applicable copyright laws is the responsibility of the user. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Microsoft Corporation. If, however, your only means of access is electronic, permission to print one copy is hereby granted.

Portions of this document specify and accompany software that is still in development. Some of the information in this documentation may be inaccurate or may not be an accurate representation of the functionality of final documentation or software. Microsoft assumes no responsibility for any damages that might occur directly or indirectly from these inaccuracies.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

©1997-1998 Microsoft Corporation. All rights reserved.

Microsoft, MS, Win32, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.


Welcome To Windows Sockets 2 SPI

This document describes the Windows Sockets 2 Service Provider Interface (SPI). It consists, primarily, of information from the Windows Sockets 2 SPI specification, but also includes additional information. The information in this document is not presented in exactly the same way as specification.


SPI: Using This Document

This document provides the on-line material needed to create Windows Sockets service or transport providers for the Windows NT and the Windows 95 operating systems, using the Microsoft implementation of Windows Sockets 2. It is intended as a reference tool and outlines the functions of the Windows Sockets SPI.

You should be familiar with Win32 programming concepts and the Windows Sockets API to make the best use of this document. Thus, you may want to refer to other references that provide a more systematic guide to writing Windows Sockets applications.

Note This documentation is intended for service provider developers, also known as transports. If you are developing a Windows Sockets 2 application, see the Win32 Software Development Kit.


SPI: Overview of Windows Sockets 2

Windows Sockets 2 utilizes the sockets paradigm that was first popularized by Berkeley Software Distribution (BSD) UNIX. It was later adapted for Microsoft Windows in the Windows Sockets 1.1.

One of the primary goals of Windows Sockets 2 has been to provide a protocol-independent interface fully capable of supporting the emerging networking capabilities, such as real-time multimedia communications.

Windows Sockets 2 is an interface, not a protocol. As an interface, it is used to discover and utilize the communications capabilities of any number of underlying transport protocols. Because it is not a protocol, it does not in any way affect the "bits on the wire", and does not need to be utilized on both ends of a communications link.

Windows Sockets programming previously centered around TCP/IP. Some of the programming practices that worked with TCP/IP do not work with every protocol. As a result, the Windows Sockets 2 API added new functions where necessary that, in turn, must be implemented in the underlying service provider.

Windows Sockets 2 has changed its architecture to provide easier access to multiple transport protocols. Following the Windows Open System Architecture (WOSA) model, Windows Sockets 2 now defines a standard service provider interface (SPI) between the application programming interface (API), with its functions exported from WS2_32.DLL, and the protocol stacks. Consequently, Windows Sockets 2 support is not limited to TCP/IP protocol stacks as is the case for Windows Sockets 1.1. For more information, see Windows Sockets 2 Architectural Overview.

There are new challenges in developing Windows Sockets 2 applications. When sockets only supported TCP/IP, a developer could create an application that supported only two socket types: connectionless and connection-oriented. Connectionless protocols used SOCK_DGRAM sockets and connection-oriented protocols used SOCK_STREAM sockets. Now, these are just two of the many new socket types. Additionally, developers can no longer rely on socket type to describe all the essential attributes of a transport protocol.

The service provider is created by implementing the functions defined in this document. This is a new challenge differing significantly from Windows Sockets 1.1.


SPI: Windows Sockets 2 Features

The new Windows Sockets 2 extends functionality in a number of areas.

Windows Sockets 2 Features

Access to protocols other than TCP/IP | Windows Sockets 2 allows an application to use the familiar socket interface to achieve simultaneous access to a number of installed transport protocols.
Overlapped I/O with scatter/gather | Windows Sockets 2 incorporates the overlapped paradigm for socket I/O and incorporates scatter/gather capabilities as well, following the model established in Win32 environments.
Protocol-independent name resolution facilities: | Windows Sockets 2 includes a standardized set of functions for querying and working with the myriad of name resolution domains that exist today (for example DNS, SAP, and X.500).
Protocol-independent multicast and multipoint: | Windows Sockets 2 applications discover what type of multipoint or multicast capabilities a transport provides and use these facilities in a generic manner.
Quality of service | Window Sockets 2 establishes conventions applications use to negotiate required service levels for parameters such as bandwidth and latency. Other QOS-related enhancements mechanisms for network-specific QOS extensions.
Other frequently requested extensions | Windows Sockets 2 incorporates shared sockets and conditional acceptance; exchange of user data at connection setup/teardown time; and protocol-specific extension mechanisms.


SPI: Microsoft Extensions and Windows Sockets 2

The Windows Sockets 2 specification defines an extension mechanism that exposes advanced transport functionality to application programs. See the SPI: Function Extension Mechanism section. The following Microsoft-specific extensions that were added to Windows Sockets 1.1 are also available to Windows Sockets 2 applications.

AcceptEx

GetAcceptExSockaddrs

TransmitFile

WSARecvEx

These functions are not exported from the WS2_32.DLL; they are exported from MSWSOCK.DLL.

An application written to use the Microsoft-specific extensions to Windows Sockets will not run correctly over a Windows Sockets service provider that does not support those extensions.


SPI: Socket Handles for Windows Sockets 2

A socket handle can optionally be a file handle In Windows Sockets 2. It is possible to use socket handles with ReadFile, WriteFile, ReadFileEx, WriteFileEx, DuplicateHandle, and other Win32 functions. Not all transport service providers will support this option. For an application to run over the widest possible number of service providers, it should not assume that socket handles are file handles.

Windows Sockets 2 has expanded certain functions used for transferring data between sockets using handles. The functions offer advantages specific to sockets for transferring data and include WSARecv, WSASend, and WSADuplicateSocket.


Windows Sockets 2 Architectural Overview

This chapter provides an overview of the Windows Sockets 2 architecture. It describes and illustrates the relationships between applications, the Windows Sockets 2 DLL and Windows Sockets service providers. A high-level view of the division of responsibilities between the Windows Sockets 2 DLL and the Windows Sockets service providers is also provided.


Windows Sockets 2 as a WOSA Component

The Windows Sockets 2 network transport and name resolution services are provided as a WOSA (Windows Open Services Architecture) component. They consist of both an application programming interface (API) used by applications and service provider interfaces (SPI's) implemented by service providers. This document defines the service provider interfaces for data transport and name resolution. While it is designed to be a stand-alone reference for the implementors of Windows Sockets 2 service providers, developers are strongly encouraged to obtain and become familiar with the Windows Sockets 2 Application Programming Interface as well.

Windows Open Service Architecture (WOSA) provides a common set of interfaces for connecting front-end applications with back-end services. The front-end application and back-end services need not speak each other's language in order to communicate as long as they both know how to talk to their respective WOSA interfaces. As a result, WOSA allows application developers and vendors of back-end services to mix and match applications and services to build solutions that shield programmers and users from the underlying complexity of the system. WOSA defines an abstraction layer to heterogeneous computing resources through the WOSA set of APIs. Because this set of APIs is extensible, new services and their corresponding APIs can be added as needed. Applications written to the WOSA APIs have access not only to all the various computing environments supported today, but also to all additional environments as they become available. Moreover, applications don't have to be modified in any way to enjoy this support.

Each service recognized by WOSA also has a set of interfaces that service-provider vendors use to take advantage of the seamless interoperability that WOSA provides. In order to provide transparent access for applications, each implementation of a particular WOSA service simply needs to support the functions defined by its service provider interface.

Like most WOSA components, Windows Sockets 2 uses a Windows dynamic-link library (DLL) that allows applications and service providers software components to be bound together at runtime. In this way, applications are able to connect to services dynamically. An application needs to know only the definition of the interface, not its implementation.


Windows Sockets 2 DLLs

Windows Sockets 2 DLL

Windows Sockets network services follow the WOSA model, meaining his means that there exists a Windows Sockets Application Programming Interface (API), which is the application programmer's access to network services, Windows Sockets Service Provider Interfaces (SPIs) which are implemented by transport service provider and name resolution service provider vendors, and WS2_32.DLL. Windows Sockets 2's WOSA compliant architecture is illustrated below.

Windows Sockets 2 Architecture

The SPI is intended to be used within all 32-bit implementations and versions of Microsoft Windows including Windows NT and Windows 95.


Function Interface Model

Windows Sockets transport and name space service providers are DLLs with a single EXPORTED procedure entry point for the service provider initialization function WSPStartup or NSPStartup, respectively. All other service provider functions are made accessible to the WS2_32.DLL via the service provider's dispatch table. Service provider DLL's are loaded into memory by the WS2_32.DLL only when needed, and are unloaded when their services are no longer required.

The SPI also defines several circumstances in which a transport service provider calls up into the WS2_32.DLL ("upcalls") to obtain DLL support services. The transport service provider DLL is given the WS2_32.DLL's upcall dispatch table via the UpcallTable parameter to WSPStartup.

Service providers should have their file extension changed from ".DLL" to ".WSP" or ".NSP". This requirement is not strict. A service provider will still operate with the WS2_32.DLL with any file extension.


Naming Conventions

The Windows Sockets SPI uses the following function prefix naming convention:

WSP (Windows Sockets Service Provider) - transport service provider entry points

WPU (Windows Sockets Provider Upcall) - WS2_32.DLL entry points for service providers

WSC (Windows Sockets Configuration) - WS2_32.DLL entry points for installation applets

NSP (Name Space Provider) - name space provider entry points

As described above, these entry points are not exported (with the exception of WSPStartup and NSPStartup), but are accessed via an exchange of dispatch tables.


Windows Sockets 2 Service Providers

As shown in the figure, Windows Sockets 2 Architecture, there are two basic types of service providers: transport providers and name space providers. Examples of transport providers include protocol stacks such as TCP/IP or IPX/SPX, while an example of a name space provider would be an interface to the Internet's Domain Naming System (DNS). Separate sections of the service provider interface specification apply to each type of service provider.

Transport and name space service providers must be registered with the WS2_32.DLL at the time they are installed. This registration need only be done once for each provider as the necessary information is retained in persistent storage.


Transport Service Providers

A given transport service provider supports one or more protocols. For example, a TCP/IP provider would supply (as a minimum) the TCP and UDP protocols, while an IPX/SPX provider might supply IPX, SPX and SPX II. Each protocol supported by a particular provider is described by a WSAPROTOCOL_INFOW structureure, and the total set of such structureures can be thought of as the catalog of installed protocols. Applications can retrieve the contents of this catalog (see WSAEnumProtocols), and by examining the available WSAPROTOCOL_INFOW structures discover the communications attributes associated with each protocol.

SPI: Layered Protocols and Protocol Chains

Windows Sockets 2 accommodates the notion of a layered protocol. A layered protocol is one that implements only higher level communications functions, while relying on an underlying transport stack for the actual exchange of data with a remote endpoint. An example of such a layered protocol would be a security layer that adds protocol to the connection establishment process in order to perform authentication and to establish a mutually agreed upon encryption scheme. Such a security protocol would generally require the services of an underlying reliable transport protocol such as TCP or SPX. The term base protocol refers to a protocol such as TCP or SPX which is fully capable of performing data communications with a remote endpoint, and the term layered protocol is used to describe a protocol that cannot stand alone. A protocol chain would then be defined as one or more layered protocols strung together and anchored by a base protocol.

This stringing together of layered protocols and base protocols into chains can be accomplished by arranging for the layered protocols to support the Windows Sockets 2 SPI at both their upper and lower edges. A special WSAPROTOCOL_INFOW structure is created which refers to the protocol chain as a whole, and which describes the explicit order in which the layered protocols are joined. This is illustrated below.

Layered Protocol Architecture


Name Space Service Providers

A name space provider implements an interface mapping between the Windows Sockets 2 name space SPI and the native programmatic interface of an existing name service such as DNS, X.500, Netware Directory Services (NDS), etc. While a name space provider supports exactly one name space, it is possible for multiple providers for a given name space to be installed. It is also possible for a single DLL to instantiate multiple different name space providers. As name space providers are installed, a catalog of WSANAMESPACE_INFO structures is maintained. An application may use WSAEnumNameSpaceProviders to discover which name spaces are supported on a machine. Refer to Section Name Resolution Service Provider Requirements for detailed information.

Legacy GetXbyY Service Providers

Windows Sockets 2 fully supports the TCP/IP-specific name resolution facilities found in Windows Sockets version 1.1. It does this by including the set of GetXbyY functions in the SPI, however the treatment of this set of functions is somewhat different from the rest of the SPI functions. The GetXbyY functions appearing in the SPI are prefaced with GETXBYYSP_, and are summarized as follows:

Berkeley style functions

SPI Function Name | Description
GETXBYYSP_gethostbyaddr | Supply a hostent structure for the specified host address
GETXBYYSP_gethostbyname | Supply a hostent structure for the specified host name
GETXBYYSP_getprotobyname | Supply a protoent structure for the specified protocol name
GETXBYYSP_getprotobynumber | Supply a protoent structure for the specified protocol number
GETXBYYSP_getservbyname | Supply a servent structure for the specified service name
GETXBYYSP_getservbyport | Supply a servent structure for the service at the specified port
GETXBYYSP_gethostname | Return the standard host name for the local machine

Async style functions

SPI Function Name | Description
GETXBYYSP_WSAAsyncGetHostByAddr | Supply a hostent structure for the specified host address
GETXBYYSP_WSAAsyncGetHostByName | Supply a hostent structure for the specified host name
GETXBYYSP_WSAAsyncGetProtoByName | Supply a protoent structure for the specified protocol name
GETXBYYSP_WSAAsyncGetProtoByNumber | Supply a protoent structure for the specified protocol number
GETXBYYSP_WSAAsyncGetServByName | Supply a servent structure for the specified service name
GETXBYYSP_WSAAsyncGetServByPort | Supply a servent structure for the service at the specified port
GETXBYYSP_WSACancelAsyncRequest | Cancel an asynchronous GetXbyY operation

The syntax and semantics of these GetXbyY functions are exactly the same as is documented in the Windows Sockets 2 API Specification and are, therefore, not repeated in this document.

The Windows Sockets 2 DLL allows exactly one service provider to offer these services. Therefore, there is no need to include pointers to these functions in the proc table received from service providers at startup time. In 32 bit environments the path to the DLL which implements these functions is retrieved from the registry key named:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\WinSock2\
    Parameters\GetXByYLibraryPath

Warning How the path is obtained in 16 bit environments has not yet been determined.

Built-In Default GetXbyY Service Provider

A default GetXbyY service provider is integrated into the standard Windows Sockets 2 runtime components. This default provider implements all of the the above functions, thus it is not required for these functions to be implemented by any name space provider. However, a name space proivder is free to provide any or all of these functions (and thus override the defaults) by simply storing the string which is the path to the DLL which implements these functions in the indicated registry key. Any of the GetXbyY functions not exported by the named provider DLL will be supplied via the built-in defaults. Note, however, that if a provider elects to supply any of the async version of the GetXbyY functions, he should supply all of the async functions so that the cancel operation will work appropriately.

For 32 bit environments, the current implementation of the default GetXbyY service provider resides within Microsoft's WSOCK32.DLL. Depending on how the TCP/IP settings have been established via the control panel, name resolution will occur using either DNS or local host files. When DNS is used, the default GetXbyY service provider uses standard Windows Sockets 1.1 API calls to communicate with the DNS server. These transactions will occur using whatever TCP/IP stack is configured as the default TCP/IP stack. Two special cases occurs, however, deserve special mention.

The default implementation of GETXBYYSP_gethostname obtains the local host name from the registry. This will correspond to the name assigned to "my computer". The default implementation of GETXBYYSP_gethostbyname and GETXBYYSP_WSAAsyncGetHostByName always compares the supplied host name with the local host name. If they match, the default implementation uses a private interface to probe the Microsoft TCP/IP stack in order to discover its local IP address. Thus, in order to be completely independent of the Microsoft TCP/IP stack, a name space provider must implement both GETXBYYSP_gethostbyname and GETXBYYSP_WSAAsyncGetHostByName.


Windows Sockets 2 Identifiers

A Windows Sockets 2 clearinghouse has been established for service provider vendors to obtain unique identifiers for new address families, socket types, and protocols. FTP and world-wide web servers are used to supply current identifier/value mappings, and email is used to request allocation of new ones. At the time of this writing the world-wide web URL for the Windows Sockets 2 Identifier Clearinghouse is

http://www.stardust.com/wsresource/winsock2/ws2ident.html


Data Transport Providers

The following sections apply only to data transport service providers and the data transport portion of the SPI.


Transport Division of Responsibilities Between DLL and Service Providers

This section provides an overview of the division of responsibility between the WS2_32.DLL and transport service providers.

WS2_32.DLL Functionality for Transport

The major task of the data transport portion of the WS2_32.DLL is to serve as a sort of "traffic manager" between service providers and applications. Consider several different service providers interacting with the same application. Each service provider interacts strictly with the WS2_32.DLL. The WS2_32.DLL takes care of (1) selecting an appropriate service provider for creating sockets based on a protocol description and (2) forwarding application procedure calls involving a socket to the appropriate service provider that created or controls that socket. Service providers are unaware that any of this is happening. They do not need to be concerned about the details of cooperating with one another or even the existence of other service providers. By abstracting the service providers into a consistent DLL interface and performing this automatic traffic routing function, the WS2_32.DLL allows applications to interact with a variety of providers without requiring the applications to be aware of the divisions between providers, where different providers are installed.

The WS2_32.DLL relies on the parameters of the API socket creation functions (socket and WSASocket) to determine which service provider to utilize. The selected transport service provider will be invoked via the WSPSocket function. In the case of the socket function, the WS2_32.DLL finds the first entry in the set of installed WSAPROTOCOL_INFOW structures that matches the values supplied in the tuple formed by the (address family, socket type, protocol) parameters. To preserve backward compatibility, the WS2_32.DLL treats the value of zero for either address family or socket type as a wild card value. The value of zero for protocol is not considered a wild card value by the WS2_32.DLL unless such behavior is indicated for a particular protocol by having the PFL_MATCHES_PROTOCOL_ZERO flag set in the WSAPROTOCOL_INFOW structureure.

For the WSASocket function, if NULL is supplied for lpProtocolInfo, the behavior is exactly as just described for socket. If a WSAPROTOCOL_INFO structure is referenced, however, the WS2_32.DLL does not perform any matching function but immediately relays the socket creation request to the transport service provider associated with the indicated WSAPROTOCOL_INFO structure. The values for the (address family, socket type, protocol) tuple are supplied intact to the service provider in the WSPSocket function. Service providers are free to ignore or pay attention to the values of the (address family, socket type, protocol) parameters as is appropriate, but they must not indicate an error condition when the value of either address family or socket type is zero. In addition, service providers must not indicate an error condition when the manifest constant FROM_PROTOCOL_INFO is contained in any of the (address family, socket type, protocol) parameters. This value simply indicates that the application wishes to use the values found in the corresponding fields of the WSAPROTOCOL_INFO structure: (iAddressFamily, iSocketType, iProtocol).

As part of socket creation a service provider informs the WS2_32.DLL about the association between itself and the new socket by means of parameters passed to WPUCreateSocketHandle or WPUModifyIFSHandle. The WS2_32.DLL keeps track of this association between socket handles and particular service providers. Whenever an application interface function that refers to a socket handle is called, the WS2_32.DLL looks up the association and calls the corresponding service provider interface function of the appropriate service provider.

In addition to its major "traffic routing" service, the WS2_32.DLL provides a number of other services such as protocol enumeration, socket descriptor management (allocation, deallocation, and context value association) for non-file-system service providers, blocking hook management on a per-thread basis, byte swapping utilities, queuing of asynchronous procedure calls (APCs) to facilitate invocation of I/O completion routines, and version negotiation between applications and the WS2_32.DLL, as well as between the WS2_32.DLL and service providers.

Transport Service Provider Functionality

Service providers implement the actual transport protocol which includes such functions as setting up connections, transferring data, exercising flow control and error control, etc. The WS2_32.DLL has no knowledge about how requests to service providers are realized; this is up to the service provider implementation. The implementation of such functions may differ greatly from one provider to another. Service providers hide the implementation-specific details of how network operations are accomplished.

Transport service providers can be broadly divided into two categories: those whose socket descriptors are real file system handles are hereafter referred to as Installable File System (IFS) providers. The remainder are referred to as non-IFS providers. The WS2_32.DLL always passes the transport service provider's socket descriptor on up to the Windows Sockets application, so applications are free to take advantage of socket descriptors that are file system handles if they so choose.

To summarize: service providers implement the low-level network-specific protocols. The WS2_32.DLL provides the medium-level traffic management that interconnects these transport protocols with applications. Applications in turn provide the policy of how these traffic streams and network-specific operations are used to accomplish the functions desired by the user.


Transport Mapping Between API and SPI Functions

The Windows Sockets Transport SPI is similar to the Windows Sockets API in that all the basic socket functions appear. When a new Windows Sockets 2 version of a function and the original Windows Sockets 1.1 version of a function both exist in the API, only the new version will show up in the SPI. For example, connect and WSAConnect both map to WSPConnect, accept and WSAAccept map to WSPAccept, and socket and WSASocket map to WSPSocket. Other API functions that are collapsed into the enhanced versions in SPI include send, sendto, recv, recvfrom, and ioctlsocket.

Support functions like htonl, htons, ntohl, and ntohs are implemented in the WS2_32.DLL, and are not passed down to service providers. The same holds true for the WSA versions of these functions.

Windows Sockets service provider enumeration and the blocking hook related functions are realized in the WS2_32.DLL, thus WSAEnumProtocols, WSAIsBlocking, WSASetBlockingHook, and WSAUnhookBlockingHook do not appear as SPI functions.

Since error codes are returned along with SPI functions, equivalents of WSAGetLastError and WSASetLastError are not needed in the SPI.

The event object manipulation and wait functions including WSACreateEvent, WSACloseEvent, WSASetEvent, WSAResetEvent, and WSAWaitForMultipleEvents are mapped directly to native OS services and thus are not present in the SPI.

All the TCP/IP specific name conversion and resolution functions in Windows Sockets 1.1 such as getXbyY, WSAAsyncGetXByY and WSACancelAsyncRequest, as well as gethostname are implemented within the WS2_32.DLL in terms of the new name resolution facilities. See Windows Sockets 1.1 Compatibile Name Resolution for TCP/IP for details. Conversion functions such as inet_addr and inet_ntoa are implemented within the WS2_32.DLL.


SPI: Function Extension Mechanism

Since the WinSock DLL itself is no longer supplied by each individual stack vendor, it is no longer possible for a stack vendor to offer extended functionality by just adding entry points to the WinSock DLL. To overcome this limitation, Windows Sockets 2 takes advantage of the new WSAIoctl function to accommodate service providers who wish to offer provider-specific functionality extensions. This mechanism presupposes, of course, that an application is aware of a particular extension and understands both the semantics and syntax involved. Such information would typically be supplied by the service provider vendor.

In order to invoke an extension function, the application must first ask for a pointer to the desired function. This is done via the WSAIoctl function using the SIO_GET_EXTENSION_FUNCTION_POINTER command code. The input buffer to the WSAIoctl function contains an identifier for the desired extension function and the output buffer will contain the function pointer itself. The application can then invoke the extension function directly without passing through the WS2_32.DLL.

The identifiers assigned to extension functions are globally unique identifiers (GUIDs) that are allocated by service provider vendors. Vendors who create extension functions are urged to publish full details about the function including the syntax of the function prototype. This makes it possible for common and/or popular extension functions to be offered by more than one service provider. An application can obtain the function pointer and use the function without needing to know anything about the particular service provider that implements the function.


Transport Configuration and Installation

In order for a transport protocol to be accessible via Windows Sockets it must be properly installed on the system and registered with Windows Sockets. When a transport service provider is installed by invoking a vendor's installation program, configuration information must be added to a configuration database to give the WS2_32.DLL required information regarding the service provider. The WS2_32.DLL exports an installation function, WSCInstallProvider for the vendor's installation program to supply the relevant information about the to-be-installed service provider, e.g., the name and path to the service provider DLL and a list of WSAPROTOCOL_INFOW structureures that this provider can support. Symmetrically, the WS2_32.DLL also provides a function, WSCDeinstallProvider, for a vendor's deinstallation program to remove all the relevant information from the configuration database maintained by the WS2_32.DLL. The exact location and format of this configuration information is private to the WS2_32.DLL, and can only be manipulated by the above-mentioned functions.

The order in which transport service providers are initially installed governs the order in which they are enumerated through WSCEnumProtocols at the service provider interface, or through WSAEnumProtocols at the application interface. More importantly, this order also governs the order in which protocols and service providers are considered when a client requests creation of a socket based on its address family, type, and protocol identifier. Windows Sockets 2 includes an applet called SPORDER.EXE that allows the catalog of installed protocols to be re-ordered interactively after protocols have already been installed. Windows Sockets 2 also includes an auxiliary DLL, SPORDER.DLL, that exports a procedural interface for re-ordering protocols. This procedural interface is described in Service Provider Ordering.

Installing Layered Protocols and Protocol Chains

The WSAPROTOCOL_INFO structure supplied with each protocol to be installed indicates whether the protocol is a base protocol, layered protocol or protocol chain. The value of the ProtocolChain.ChainLen field is interpreted as follows:

0 | Layered protocol
1 | Base protocol (or chain with only one component)
>1 | Protocol chain

Installation of protocol chains can only occur after successful installation of all of the constituent components (base protocols and layered protocols). The WSAPROTOCOL_INFOW structure for a protocol chain uses the ProtocolChain field to describe the length of the chain and the identity of each component. The individual protocols that make up a chain are listed in order in the ProtocolChain.ChainEntries array, with the zeroth element of the array corresponding to the first layered provider. Protocols are identified by their CatalogEntryID values, which are assigned by the WS2_32.DLL at protocol installation time, and can be found in the WSAPROTOCOL_INFOW structure for each protocol.

The values for the remaining fields in the protocol chain's WSAPROTOCOL_INFOW structure should be chosen to reflect the attributes and identifiers that best characterize the protocol chain as a whole. When selecting these values, developers should bear in mind that communications over protocol chains can only occur when both endpoints have compatible protocol chains installed, and that applications must able to recognize the corresponding WSAPROTOCOL_INFO structure.

When a base protocol is installed, it is not necessary to make any entries in the ProtocolChain.ChainEntries array. It is implicitly understood that the sole component of this chain is already identified in the CatalogEntryID field of the same WSAPROTOCOL_INFO structure. Also note that protocol chains may not include multiple instances of the same layered protocol.


Name Resolution Providers

The following sections apply only to name resolution service providers and the name resolution portion of the SPI.


SPI: Name Resolution Model

In developing a protocol-independent client/server application, there are two basic requirements that exist with respect to name resolution and registration:

  • The ability of the server half of the application (hereafter referred to as a service) to register its existence within (or become accessible to) one or more name spaces
  • The ability of the client application to find the service within a name space and obtain the required transport protocol and addressing information

For those accustomed to developing TCP/IP based applications, this may seem to involve little more than looking up a host address and then using an agreed upon port number. Other networking schemes, however, allow the location of the service, the protocol used for the service, and other attributes to be discovered at run-time. To accommodate the broad diversity of capabilities found in existing name services, the Windows Sockets 2 interface adopts the model described below.

A name space refers to some capability to associate (as a minimum) the protocol and addressing attributes of a network service with one or more human-friendly names. Many name spaces are currently in wide use including the Internet's Domain Name System(DNS), Netware Directory Services (NDS), X.500, etc. These name spaces vary widely in how they are organized and implemented. Some of their properties are particularly important to understand from the perspective of Windows Sockets name resolution.

SPI: Types of Name Spaces

There are three different types of name spaces in which a service could be registered:

  • dynamic
  • static
  • persistent

Dynamic name spaces allow services to register with the name space on the fly, and for clients to discover the available services at run-time. Dynamic name spaces frequently rely on broadcasts to indicate the continued availability of a network service. Examples of dynamic name spaces include the SAP name space used within a Netware environment and the NBP name space used by Appletalk.

Static name spaces require all of the services to be registered ahead of time, i.e. when the name space is created. The DNS is an example of a static name space. Although there is a programmatic way to resolve names, there is no programmatic way to register names.

Persistent name spaces allow services to register with the name space on the fly. Unlike dynamic name spaces however, persistent name spaces retain the registration information in non-volatile storage where it remains until such time as the service requests that it be removed. Persistent name spaces are typified by directory services such as X.500 and the NDS (Netware Directory Service). These environments allow the adding, deleting, and modification of service properties. In addition, the service object representing the service within the directory service could have a variety of attributes associated with the service. The most important attribute for client applications is the service's addressing information.

SPI: Name Space Organization

Many name spaces are arranged hierarchically. Some, such as X.500 and NDS, allow unlimited nesting. Others allow services to be combined into a single level of hierarchy or "group." This is typically referred to as a workgroup. When constructureing a query, it is often necessary to establish a context point within a name space hierarchy from which the search will begin.

SPI: Name Space Provider Architecture

Naturally, the programmatic interfaces used to query the various types of name spaces and to register information within a name space (if supported) differ widely. A name space provider is a locally-resident piece of software that knows how to map between Windows Sockets's name space SPI and some existing name space (which could be implemented locally or be accessed via the network). This is illustrated as follows:

Name Space Provider Architecture

Note Note that it is possible for a given name space, say DNS, to have more than one name space provider installed on a given machine.

As mentioned above, the generic term service refers to the server-half of a client/server application. In Windows Sockets, a service is associated with a service class, and each instance of a particular service has a service name which must be unique within the service class. Examples of service classes include FTP Server, SQL Server, XYZ Corp. Employee Info Server, etc. As the example attempts to illustrate, some service classes are "well known" while others are very unique and specific to a particular vertical application. In either case, every service class is represented by both a class name and a class ID. The class name does not necessarily need to be unique, but the class ID must be. Globally Unique Identifiers (GUIDs) are used to represent service class IDs. For well-known services, class names and class ID's (GUIDs) have been pre-allocated, and macros are available to convert between, for example, TCP port numbers and the corresponding class ID GUIDs. For other services, the developer chooses the class name and uses the UUIDGEN.EXE utility to generate a GUID for the class ID.

The notion of a service class exists to allow a set of attributes to be established that are held in common by all instances of a particular service. This set of attributes is supplied to Windows Sockets at the time the service class is defined, and is referred to as the service class schema information. The WS2_32.DLL in turns relays this information to all active name space providers. When an instance of a service is installed and made available on a host machine, that service is considered instantiated, and its service name is used to distinguish this particular instance of the service from other instances which may be known to the name space.

Note that the installation of a service class only needs to occur on machines where the service executes, not on all of the clients which may utilize the service. Where possible, the WS2_32.DLL will provide service class schema information to a name space provider at the time an instantiation of a service is to be registered or a service query is initiated. The WS2_32.DLL does not, of course, store this information itself, but attempts to retrieve it from a name space provider that has indicated its ability to supply this data. Since there is no guarantee that the WS2_32.DLL will be able to supply the service class schema, name space providers that need this information must have a fallback mechanism to obtain it through name space-specific means.

The Internet's Domain Name System does not have a well-defined means to store service class schema information. As a result, DNS name space providers will only be able to accommodate well-known TCP/IP services for which a service class GUID has been preallocated. In practice this is not a serious limitation since service class GUIDs have been preallocated for the entire set of TCP and UDP ports, and macros are available to retrieve the GUID associated with any TCP or UDP port. Thus all of the familiar services such as ftp, telnet, whois, etc. are well supported. When querying for these services, by convention the host name of the target machine is the service instance name.

Continuing with our service class example, instance names of the ftp service may be "alder.intel.com" or "rhino.microsoft.com" while an instance of the XYZ Corp. Employee Info Server might be named "XYZ Corp. Employee Info Server Version 3.5". In the first two cases, the combination of the service class GUID for ftp and the machine name (supplied as the service instance name) uniquely identify the desired service. In the third case, the host name where the service resides can be discovered at service query time, so the service instance name does not need to include a host name.


Name Resolution Division of Responsibilities Between DLL and Service Providers

The following paragraphs describe how the WS2_32.DLL and the name space providers cooperate together to implement the name resolution services supported by the Windows Sockets 2 API.

WS2_32.DLL Functionality for Name Resolution

The WS2_32.DLL manages the registration and demand loading of individual name space provider DLLs. It also is responsible for routing name space operations from a Windows Sockets 2 application to the appropriate set of name space providers. This mapping is governed by the value of name space and service provider ID parameters that are found in individual API functions. As a general rule, when a specific name space provider is referenced, the operation is only routed to identified provider. If the name space provider ID is NULL but a particular name space is referenced, the operation is routed to all name space providers that support the identified name space. If the name space provider ID is NULL and the name space identifier is given as NS_ALL, then the operation is routed to all active name space providers.

As part of starting a query to one or more service providers the WS2_32.DLL allocates an object to keep track of the ongoing state of the query. An opaque handle representing this object is returned to the application that started the query. The application supplies this handle as a parameter each time it repetitively calls an application interface function to retrieve the next unit of data resulting from the query. In response to these application interface procedure calls, the WS2_32.DLL uses the information it stores in the object make corresponding calls to the name space providers involved in the query. The WS2_32.DLL updates the information in its object as each successive application interface call occurs so that the corresponding calls to name space providers progress appropriately through all of the name space providers involved in the query.

Name Space Provider Functionality

Each name space provider is responsible for mapping the set of functions appearing in the Windows Sockets 2 name resolution SPI to the appropriate transactions with the supported name space. In some cases, this is primarily a matter of mapping the SPI interface to whatever native interface exists for the name space. In others, the name space provider must conduct transactions with the name space provider over the network. Some name space providers will do this by making calls to the Windows Sockets API, others will use private interfaces to associated transport stacks.


Name Resolution Mapping Between API and SPI Functions

The installation of service classes, registration of service instantiations and basic query operations all map fairly directly from the API to the SPI. The WSAGetServiceClassNameByServiceClassId function does not have a corresponding function in the SPI, as this function is implemented in WS2_32.DLL by making a call to NSPGetServiceClassInfo.

The helper functions WSAAddressToString and WSAStringToAddress are mapped to the corresponding functions in the transport API, as only a transport provider will necessarily know how to perform the translation on a sockaddr structureure.


Name Resolution Configuration and Installation

In order for a name space provider to be accessible via Windows Sockets it must be properly installed on the system and registered with Windows Sockets. When a name space provider is installed by invoking a vendor's installation program, configuration information must be added to a configuration database to give the WS2_32.DLL required information regarding the service provider. The WS2_32.DLL exports an installation function, WSCInstallNameSpace, for the vendor's installation program to use in supplying the relevant information about the to-be-installed service provider. This includes the following:

  • Provider Name - A string representing the provider for display in the control panel
  • Provider Version - The version of this provider
  • Provider Path - A path name to the provider dll
  • Name Space - The name space supported by the provider
  • Provider GUID - A unique, vendor-supplied number representing this provider/name space combination. This is used as a key for all subsequent references to this provider, and for uninstall. These values are created using the UUIDGEN.EXE utility.
  • Stores all flag - a flag indicating whether this name space provider will be responsible for retaining all service class schema information for all service classes. If such a provider exists, the WS2_32.DLL does not need to query each individual name space provider for this information.

Symmetrically, the WS2_32.DLL also provides a function, WSCUnInstallNameSpace, for a vendor's deinstallation program to remove all the relevant information from the configuration database. The exact location and format of this configuration information is private to the WS2_32.DLL, and can only be manipulated by the above-mentioned functions.

At any point in time a name space provider is considered to be either active or inactive, with this setting controlled via the WSCEnableNSProvider function. Name space providers that are inactive continue to show up when enumerated via WSAEnumNameSpaceProviders, but the WS2_32.DLL will not route any query or service registration operations to these providers. This capability can be useful in situations where more than one of the installed name space providers can support a given name space.

When multiple name space providers are referenced in a single API function, the order in which the order in which the queries and registration operations are routed to name space providers is unspecified. The order is unrelated to the order in which name space providers are installed. There are two ways to control which name space providers are used to resolve a name query. First, the name space configuration function, WSCEnableNSProvider can be used to enable and disable name spaces in a machine-wide, persistent way. Second, applications can direct an individual query to a particular provider by specifying that provider's identifying GUID as part of the query.


Windows Sockets 2 Transport Provider Requirements

The sections which follow provide a description of each of the functional areas which transport service providers are required to implement. Where appropriate, implementation considerations and guidelines are also provided.


Service Provider Activation

The following sections describe the sequence of events involved in bringing a transport service provider DLL into memory, initializing it, and, eventually, de-initializing it.


Initialization

The WS2_32.DLL loads the service provider's interface DLL into the system by using the standard Windows dynamic library loading mechanisms, and initializes it by calling WSPStartup. This is usually triggered by an application calling either socket or WSASocket in order to create a new socket that is to be associated with a service provider whose interface DLL is not currently loaded into memory. The path to each service provider's interface DLL is stored by the WS2_32.DLLat the time the service provider is being installed. See section Configuration and Installation for more information.

Over time, different versions may exist for the WinSock 2 DLLs, applications, and service providers. New versions may define new features, new fields to data structures and bit fields, etc. Version numbers therefore indicate how to interpret various data structures.

To allow optimal mixing and matching of different versions of applications, versions of the WS2_32.DLL itself, and versions of service providers by different vendors, the SPI provides a version negotiation mechanism for use between the WS2_32.DLL and the service providers. This version negotiation is handled by WSPStartup. Basically, the WS2_32.DLLpasses to the service provider the highest version numbers it is compatible with. The service provider compares this with its own supported range of version numbers. If these ranges overlap, the service provider returns a value within the overlapping portion of the range as the result of the negotiation. Usually, this should be the highest possible value. If the ranges do not overlap, the two parties are incompatible and the function returns an error.

WSPStartup must be called at least once by each client process, and may be called multiple times by WS2_32.DLLor other entities. A matching WSPCleanup must be called for each successful WSPStartup call. The service provider should maintain a reference count on a per-process basis. On each WSPStartup call, the caller may specify any version number supported by the SP DLL.

A service provider must store the pointer to the client's upcall dispatch table that is received as a WSPStartup parameter on a per-process basis. If a given process calls WSPStartup multiple times, the service provider must use only the most recently supplied dispatch table pointer.

As part of the service provider initialization process The WS2_32.DLLretrieves the service provider's dispatch table via the lpProcTable parameter in order to obtain entry points to the rest of the SPI functions specified in this document. Using a dispatch table (as opposed to the usual DLL mechanisms for accessing entry points) serves two purposes. First of all, it is more convenient for the WS2_32.DLLsince a single call can be made to discover the entire set of entry points. Secondly, this enables layered service providers formed into protocol chains to operate more efficiently.

Initializing Protocol Chains

At the time the WSAPROTOCOL_INFOW struct for a protocol chain is installed, the path to the first layered provider in the chain is also specified. When a protocol chain is initialized, the WS2_32.DLLuses this path to load the provider DLL and then invokes WSPStartup. Since WSPStartup includes a pointer to the chain's WSAPROTOCOL_INFOW struct as one of its parameters, layered providers can determine what type of chain they are being initialized into, and who the next lower layer in the chain is. A layered provider would then in turn load the next protocol provider in the chain and initialize it with a call to WSPStartup, and so forth. Whenever the next lower layer is another layered provider, the chain's WSAPROTOCOL_INFOW struct must be referenced in the WSPStartup call. When the next lower layer is a base protocol (signifying the end of the chain), the chain's WSAPROTOCOL_INFOW struct is no longer propagated downward. Instead, the current layer must reference a WSAPROTOCOL_INFOW struct that corresponds to the protocol that the base provider should use. Thus, the base provider has no notion of being involved in a protocol chain.

The dispatch table provided by any given layered provider will, in many instances, duplicate the entry points of an underlying provider. The layered provider would only insert its own entry points for functions that it needed to be directly involved in. Note, however, that it is imperative that a layered provider not modify the contents of the upcall table that it received when calling WSPStartup on the next lower layer in a protocol chain. These upcalls must be made directly to the WinSock 2 DLL.


Cleanup

The WS2_32.DLL(and layered protocols) will call WSPCleanup once for each invocation of WSPStartup. On each invocation, WSPCleanup should decrement a per-process reference counter, and when the counter reaches zero the service provider must prepare itself to be unloaded from memory. The first order of business is to finish transmitting any unsent data on sockets that are configured for a graceful close. Thereafter, any and all resources held by the provider are to be freed. The service provider must be left in a state where it can be immediately re-initialized by a call to WSPStartup.


Error Reporting and Parameter Validation

The scheme for error reporting differs between the SPI and API interfaces. Windows Sockets service providers report errors along with the function returning, as opposed to the per-thread based approach utilized in the API. The WS2_32.DLL uses the service provider's per-function error code to update the per-thread error value that is obtained via the WSAGetLastError API function. Service providers are still required, however, to maintain the per-socket based error which can be retrieved via the SO_ERROR socket option.

The WS2_32.DLL performs parameter validation only on function calls that are implemented entirely within itself. Service providers are responsible for performing all of their own parameter validation.


Byte Ordering Assumptions

A service provider should treat all sockaddr components exclusive of the address family field as if they are in the network byte order, and the address family field as in the local machine's byte order. It is the Windows Sockets application's responsibility to make sure that addresses contained in sockaddr structs are properly arranged. The Windows Sockets API provides a number of conversion routines to simplify this task. Currently these routines understand conversion between the local host's natural byte order and either "big-endian" or "little-endian" network byte ordering. Windows Sockets's architecture is such that other byte ordering schemes could be introduced in the future.


Socket Creation and Descriptor Management

The sections which follow describe aspects of creating new sockets and the allocation of socket descriptors.


Descriptor Allocation

While Windows Sockets service providers are encouraged to implement sockets as installable file system (IFS) objects, the Windows Sockets architecture also accommodates service providers whose socket handles are not IFS objects. Providers with IFS handles indicate this via the XP1_IFS_HANDLES attribute bit in the WSAPROTOCOL_INFOW struct. (Note: the XP1_IFS_HANDLES attribute bit was not included in release 2.0.8 of the API specification, but has since been added via the errata mechanism.) Windows Sockets SPI clients may take advantage of providers whose socket descriptors are IFS handles by using these descriptors with standard Win32 I/O facilities such as ReadFile and WriteFile.

Whenever an IFS provider creates a new socket descriptor, it is mandatory that the provider call WPUModifyIFSHandle prior to supplying the new handle to a Windows Sockets SPI client. This function takes a provider ID and a proposed IFS handle from the provider as input and returns a (possibly) modified handle. The IFS provider must supply only the modified handle to its client, and all requests from the client will reference only this modified handle. The modified handle is guaranteed to be indistinguishable from the proposed handle as far as the operating system is concerned. Thus in most instances, the service provider will simply choose to use only the modified handle in all of its internal processing. The purpose of this modification function is to allow the WS2_32.DLL to greatly streamline the process of identifying the service provider associated with a given socket.

Providers that do not return IFS handles must obtain a valid handle from the WS2_32.DLLvia the WPUCreateSocketHandle call. The non-IFS provider must offer only a WinSock 2 DLL-supplied handle to its client, and all requests from the client will reference only these handles. As a convenience to service provider implementors, one of the input parameters supplied by a provider in WPUCreateSocketHandle is a DWORD context value. The WS2_32.DLLassociates this context value with the allocated socket handle and allows a service provider to retrieve the context value at any time via the WPUQuerySocketHandleContext call. A typical use for this context value would be to store a pointer to a service provider maintained data structure used to store socket state information.


Socket Attribute Flags and Modes

There are several socket attributes which can be indicated via the flags parameter in WSPSocket. The WSA_FLAG_OVERLAPPED flag indicates that a socket will be used for overlapped I/O operations. Support of this attribute is mandatory for all service providers. See Overlapped I/O for more information. Note that creating a socket with the overlapped attribute has no impact on whether a socket is currently in the blocking or non-blocking mode. Sockets created with the overlapped attribute may be used to perform overlapped I/O, and doing so does not change the blocking mode of a socket. Since overlapped I/O operations do not block, the blocking mode of a socket is irrelelvant for these operations.

Four additional attribute flags are used when creating sockets that are to be used for multipoint and/or multicast operations, and support for these attributes is optional. Providers that support multipoint attributes indicate this via the XP1_SUPPPORT_MULTIPOINT bit in their respective WSAPROTOCOL_INFOW structures. See WSPSocket and section SPI: Protocol-Independent Multicast and Multipoint for the definition and usage of each of these flags. Only sockets that are created with multipoint related attributes can be used in the WSPJoinLeaf function for creating multipoint sessions.

A socket is in one of two modes, blocking and non-blocking, at any time. Sockets are created in the blocking mode by default, and can be changed to the non-blocking mode by calling WSPAsyncSelect, WSPEventSelect, or WSPIoctl. A socket can be switched back to the blocking mode by using WSPIoctl if no WSPAsyncSelect or WSPEventSelect is active. The mode for a socket only affects those functions which may block, and does not affect overlapped I/O operations. See section Blocking Operations for more information.


Closing Sockets

WSPCloseSocket releases the socket descriptor so that any pending operations in any threads of the same process will be aborted, and any further reference to it will fail. Note that a reference count should be employed for shared sockets, and only if this is the last reference to an underlying socket, should the information associated with this socket be discarded, provided graceful close is not requested (i.e., SO_DONTLINGER is not set). In the case of SO_DONTLINGER being set, any data queued for transmission will be sent if possible before information associated with the socket is released. See WSPCloseSocket for more information.

For non-IFS service providers, WPUCloseSocketHandle must be invoked to release the socket handle back to the WinSock 2 DLL.


Blocking Operations

The notion of blocking in a Windows environment has historically been a very important one. In Windows Sockets 1.1 environments, blocking calls were discouraged since they tend to disable ongoing interaction with the Windowing system, and since they employ a pseudo blocking technique which, for a variety of reasons, does not always work as intended. However, in preemptively scheduled Win32 environments such as Windows 95 and Windows NT, blocking calls make much more sense, can be implemented by native operating system services, and are in fact a generally preferred mechanism. The Windows Sockets 2 API no longer support psuedo blocking, but because the WinSock 1.1 compatibility shims must continue to emulate this behavior, service providers must support this as described below.


Pseudo vs. True Blocking

In 16 Windows environments, true blocking is not supported by the OS, thus a blocking operation which cannot be completed immediately is handled as follows. The service provider initiates the operation, and then enters a loop during which it dispatches any Windows messages (yielding the processor to another thread if necessary) and then checks for the completion of the Windows Sockets function. If the function has completed, or if WSPCancelBlockingCall has been invoked, the loop is terminated and the blocking function completes with an appropriate result. This is what is meant by the term "pseudo blocking", and the loop referred to above is known as the "default blocking hook".


Blocking Hook

Although this mechanism is sufficient for simple applications, it cannot support the complex message-dispatching requirements of more advanced applications such as those using the Multiple Document Interface (MDI) model. For such applications, a thread-specific "blocking hook" may be installed by the application. This will be called by the service provider instead of the default blocking hook described above. A service provider must retrieve a pointer to the per-thread blocking hook from the WS2_32.DLLby calling WPUQueryBlockingCallback. If the application has not installed its own blocking hook a pointer to the default blocking hook function will be returned.

A Windows Sockets service provider cannot assume that an application-supplied blocking hook allows message processing to continue as the default blocking hook does. Some applications cannot tolerate the possibility of reentrant messages while a blocking operation is outstanding. Such an application's blocking hook function would simply return FALSE. If a service provider depends on messages for its internal operation, it may execute PeekMessage(hMyWnd...) before executing the application's blocking hook so that it can get its own messages without affecting the rest of the system.

There is no default blocking hook installed in preemptive multithreaded versions of Windows. This is because other processes will not be blocked if a single application is waiting for an operation to complete (and hence not calling PeekMessage or GetMessage which causes the application to yield the processor in nonpreemptive Windows). When the service provider calls WPUQueryBlockingCallback a null pointer will be returned indicating that the provider is to use native OS blocking functions. However, in order to preserve backward compatibility, an application-supplied blocking hook can still be installed on a per-thread basis in 32 bit versions of Windows.

The Windows Sockets service provider calls the blocking hook only if all of the following are true: the routine is one which is defined as being able to block, the specified socket is a blocking socket, and the request cannot be completed immediately. If only non-blocking sockets and WSPAsyncSelect /WSPEventSelect instead of WSPSelect are used, then the blocking hook will never be called.

Important If, during the time pseudo blocking is being used to block a thread, a Windows message is received for the thread, there is a risk that the thread will attempt to issue another Windows Sockets call. Because of the difficulty of managing this condition safely, the Windows Sockets 1.1 specification disallowed this behavior. It is not permissible for a given thread to make multiple nested Windows Sockets function calls. Only one outstanding function call is allowed for a particular thread. Any nested Windows Sockets function calls fail with the error WSAEINPROGRESS. It should be emphasized that this restriction applies to both blocking and non-blocking operations, but only in WinSock 1.1 environments. There are a few exceptions to this rule, including two functions which allow an application to determine whether a pseudo blocking operation is in fact in progress, and to cancel such an operation if need be. These are described below.


Canceling Blocking Operations

A thread may, at any time, call WSAIsBlocking in order to determine whether or not a blocking call is currently in progress. (This function is implemented within the Windows Sockets 1.1 compatibility shims and hence has no SPI counterpart.) Clearly this is only possible when pseudo blocking, as opposed to true blocking, is being employed by the service provider. When necessary, WSPCancelBlockingCall may be called at any time to cancel any in-progress pseudo blocking operation.


SPI: Event Objects

Event objects are introduced in Windows Sockets 2 as a general synchronization mechanism between Windows Sockets 2 service providers and applications. They are used for a number of purposes including indicating completion of overlapped operations and indicating the occurrence of one or more network events.


Creating Event Objects

The WS2_32.DLLprovides facilities for event object creation to both applications and service providers, although in most instances event objects will be created by applications. Event object services are made available to Windows Sockets service providers via WPUCreateEvent simply as a convenience mechanism for any internal processing that may benefit from same. Note that the event object handle is only valid in the context of the calling process. In Win32 environments the realization of event objects is via the native event services provided by the operating system.


Using Event Objects

Windows Sockets event objects are fairly simple constructs which can be created and closed, set and cleared, waited upon and polled. The general usage model is for clients to create an event object and supply the handle as a parameter (or as a component of a parameter structure) in functions such as WSPSend and WSPEventSelect. When the nominated condition has occurred, the service provider uses the handle to set the event object by calling WPUSetEvent. Meanwhile, the Windows Sockets SPI client may either block and wait or poll until the event object becomes set (or as it is sometimes called: signaled). The client may subsequently clear or reset the event object and use it again.


Destroying Event Objects

The entity which creates an event object (application or service provider) is responsible for destroying it when it is no longer required. Service providers do this via WPUCloseEvent.


Notification of Network Events

One of the most important responsibilities of a data transport service provider is that of providing indications to the client when certain network events have occurred. The list of defined network events consists of the following:

  • FD_CONNECT - a connection to a remote host or to a multicast session has been completed
  • FD_ACCEPT - a remote host is making a connection request
  • FD_READ - network data has arrived which is available to be read
  • FD_WRITE - space has become available in the service provider's buffers so that additional data may now be sent
  • FD_OOB - out of band data is available to be read
  • FD_CLOSE - the remote host has closed down the connection
  • FD_QOS - a change has occurred in negotiated quality of service levels
  • FD_GROOUP_QOS - a change has occurred in negotiated quality of service levels for the socket group
  • · FD_ROUTING_INTERFACE_CHANGE – a local interface that should be used to reach the destination specified in SIO_ROUTING_INTERFACE_CHANGE IOCLT has changed
  • · FD_ADDRESS_LIST_CHANGE – the list of local addresses to which application can bind has changed

The set of network events enumerated above is sometimes referred to as the FD_XXX events. Indication that one or more of these network events have occurred may be given in a number of ways depending on how the client requests for notification.


Selects

In the original BSD sockets interface the select call was the standard (and only) means to obtain network event indications. For each socket, information on read, write, or error status can be polled or waited on. See WSPSelect for more information. Note that network events FD_QOS and FD_GROUP_QOS cannot be obtained by this approach.


Windows Messages

Windows Sockets 1.1 introduced the async select mechanism in order to provide network event indications in a manner that did not involve either polling or blocking. The WSPAsyncSelect function is used to register an interest in one or more network events as listed above, and supply a window handle to be used for notification. When a nominated network event occurs, a client-specified Windows message is sent to the indicated window. The service provider must use the WPUPostMessage function to accomplish this.

In Win32 environments, this may not be the most efficient notification mechanism, and is inconvenient for daemons and services which don't want to open any windows. The event object signaling mechanism described below is introduced to solve this problem.


Event Object Signaling

WSPEventSelect behaves exactly like WSPAsyncSelect except that, rather than cause a Windows message to be sent on the occurrence of any nominated FD_XXX network event (e.g.. FD_READ, FD_WRITE, etc.), a designated event object is set.

Also, the fact that a particular FD_XXX network event has occurred is "remembered" by the service provider. This is needed since the occurrence of any and all nominated network events will result in a single event object becoming signaled. A call to WSPEnumNetworkEvents causes the current contents of the network event memory to be copied to a client-supplied buffer and the network event memory to be cleared. The client may also designate a particular event object to be cleared atomically along with the network event memory.


SPI: Socket Groups

Important

Reserved for future use with socket groups:

Windows Sockets 2 introduces a number of function parameters, data types, structure members, and manifest constant values that are reserved for future use in grouping sockets together. As of the version 2.2.1 of the specification, the intended future use of these items is fully described, however, none of the group-related parameters is interpreted in software releases corresponding to the version 2.2.1 specification. Since a client always has the option to elect not to use socket groups, there are always default values and behaviors defined for group-related definitions. It is simple for an application not employing socket groups to use default values in such a fashion that the application will not be harmed if and when socket groups are "turned on" in the future. Definitions related to socket groups are marked in version 2.2.1 specification with the phrase: "Reserved for future use with socket groups" preceding the description of the intended future use.

Windows Sockets 2 introduces the notion of a socket group as a means for an application to indicate to the service provider that a particular set of sockets are related and that the group thus formed has certain attributes. Group attributes include relative priorities of the individual sockets within the group and a group quality of service specification.

Applications needing to exchange multimedia streams over the network are benefited by being able to establish a specific relationship among the set of sockets being utilized. As a minimum, this includes a hint to the service provider about the relative priorities of the media streams being carried. For example, a conferencing application would want to have the socket used for carrying the audio stream be given higher priority than that of the socket used for the video stream. Furthermore, there are transport providers (e.g. digital telephony and ATM) which can utilize a group quality of service specification to determine the appropriate characteristics for the underlying call or circuit connection. The sockets within a group are then multiplexed in the usual manner over this call. By allowing the application to identify the sockets that make up a group and to specify the required group attributes, such service providers can operate with maximum effectiveness.

The following paragraphs define what a service provider must do in order to implement socket grouping.


Socket Group Operations

While it is not mandatory that a service provider support socket groups, providers are strongly encouraged to do so. As shown below, implementing the minimum required behavior for socket grouping is almost trivial. The advantage to providing even a minimal grouping implementation is that applications may then depend on grouping operations being at least tolerated in all cases, with significant advantages being realized in particular cases. The paragraphs below briefly mention the SPI functions that are used to establish and utilize socket groups.

The WSPSocket and WSPAccept functions are used to explicitly create and/or join a socket group coincident with creating a new socket. Once joined, a socket remains in a socket group until the socket is closed. A socket group terminates if all of its member sockets are closed. Socket group IDs can be retrieved by using WSPGetSockOpt with option SO_GROUP_ID. Relative priority can be accessed by using WSPGetSockOpt or WSPSetSockOpt with option SO_GROUP_PRIORITY.

Group QOS can be stipulated in WSPConnect, or WSPIoctl with SIO_SET_GROUP_QOS, if the socket specified in these function is the creator of its associated socket group. WSPIoctl with SIO_GET_GROUP_QOS can be used to retrieve the associated group QOS of the specified socket. See below for more information about the QOS specification.


Required Socket Grouping Behavior

For providers that support socket groups, the following functionality is required as a minimum. The provider must be able to allocate new group IDs which need only be unique for a given service provider. At socket creation time, it must be possible to add the newly created socket to the membership of an existing group or to create a new group. If group quality of service is supported, the provider should remember which socket was the creator (i.e. originating member) of a group, and allow only that socket to specify group quality of service parameters.

There are two types of socket groups: constrained and unconstrained. Constrained groups have the property that all sockets which are members of the group must be connection-oriented and may only be connected to the same host address. The service provider should disallow a socket creation/group join operation to a constrained group if the new socket is not connection-oriented. Similarly, the service provider should disallow the connect operation if the destination address is not identical to the group's destination address. A constrained group's destination address is established when the first socket in the group becomes connected.

The only attribute that may be specified individually for grouped sockets is relative priority. Priority is only a hint. The service provider should record the assigned priority and allow this value to be retrieved, but is otherwise free to ignore it if there is no reasonable way to honor priority. Note that this specification does not define the priority relationship between grouped and ungrouped sockets, or between sockets that are members of different groups. Grouping may be (but is not required to be) a completely local mater. There is no requirement that grouping impact in any way the on-wire protocol of a transport.

It is not required for service providers that support grouping to also support group quality of service. However, a service provider is encouraged to enable this feature whenever it is supported by the underlying network technology. If group quality of service is supported, the minimum requirement is that a client must be able to set and query QOS requests. There is no requirement that the provider implement anything more than best effort service.


Recommended Socket Grouping Behavior

It is recommended that a provider implement on a local basis a relative prioritization scheme for sockets within a group. This would not have any impact on the on-wire protocol and thus does not affect interoperability. The Windows Sockets 2 prioritization scheme, which is defined only across the sockets within a single group, is both meaningful and useful when the information associated with group member sockets form an exclusive multiplex across an underlying point-to-point connection such as a telephone call, ATM switched virtual circuit, or other circuit switched connection. Decisions on how to establish a priority relationship between sockets not in the same group or not in any group are left up to the service provider implementor. Where the underlying transport protocol encompasses group semantics, it is advantageous to have the group prioritization scheme be implemented on a bilateral basis.

It is also recommended that a provider support group QOS for at least best effort service levels.


SPI: Quality of Service

The basic QOS mechanism in Windows Sockets 2 descends from the flow specification (or "flow spec") as described by Craig Partridge in RFC 1363, dated September 1992. A brief overview of this concept is as follows:


Quality of Service Overview

Flow specifications describe a set of characteristics about a proposed unidirectional flow through the network. An application may associate a pair of flowspecs with a socket (one for each direction) at the time a connection request is made via WSPConnect, or at other times via WSPIoctl with the SIO_SET_QOS/SIO_SET_GROUP_QOS command. Flowspecs indicate parametrically what level of service is required and provide a feedback mechanism for applications to use in adapting to network conditions.

The Windows Sockets 2 flow specificaitons divide QOS characteristics into the following general areas:

  1. Source Traffic Description - The manner in which the application's traffic will be injected into the network. This specification is made in terms of the token bucket traffic model and includes values for the token rate, the token bucket size, and the peak bandwidth. (The token bucket model is described further below.) Note that the bandwidth requirement being expressed in terms of a token rate does not mean that hosts must implement token buckets. Any traffic management scheme that yields equivalent behavior is permitted.
  2. Latency - Upper limits on the amount of delay and delay variation that are acceptable.
  3. Level of service guarantee - Whether or not an absolute guarantee is required as opposed to best effort. Note that providers which have no feasible way to provide the level of service requested are expected to fail the connection attempt.
  4. Provider-specific parameters - The FLOWSPEC itself can be extended in ways that are particular to specific providers.


Usage Model

The usage model for QOS in Windows Sockets 2 is as follows. QOS parameters for a socket are established using WSPIoctl with SIO_SET_QOS/SIO_SET_GROUP_QOS. For connection-oriented protocols, however, it is often most convenient for an application to stipulate its QOS request at connect time. This is manifest to the service provider via the WSPConnect function. Note that any QOS pre-set via WSPIoctl for connection-oriented sockets will be overridden if the QOS parameters in WSPConnect are non-null.

Regardless of which method is used to establish the QOS parameters, they are typically utilized by the service provider at the time a connect operation is performed. If the WSPConnect function completes successfully the client knows that its QOS request has been honored by the network, and it is then free to use the socket for data exchange. If the connect operation fails because of limited resources an appropriate error indication is given. At this point the client may scale down its service request and try again or simply give up.

Connectionless sockets may also use WSPConnect to establish a specified QOS level to a single designated peer. Otherwise the WSPIoctl with SIO_SET_QOS/SIO_SET_GROUP_QOS could be used to stipulate the initial QOS request, and any subsequent QOS renegotiations.


QOS Updates

After every connection attempt (successful or otherwise) transport providers update the associated flow spec structures in order to indicate, as well as possible, the existing network conditions. (Note that it is legal to update with the default values defined below to indicate that information about the current network conditions is not available.) This update from the service provider about current network conditions is especially useful for the case where the client's QOS request consisted entirely of the default (i.e. unspecified) values, which any service provider should be able to agree to. Clients expect to be able to use this information about current network conditions to guide their use of the network, including any subsequent QOS requests. Note however, that information provided by the transport service provider in the updated flow spec structure is only a hint and may be little more than a rough estimate that only applies to the first hop as opposed to the complete end-to-end connection.

Even after a flow is established, conditions in the network may change or one of the communicating parties may invoke a QOS renegotiation which results in a reduction (or increase) in the available service level. A notification mechanism is included which utilizes the usual Windows Sockets notification techniques for network events (FD_QOS and FD_GROUP_QOS events) to allow the service provider to indicate to the client that QOS levels have changed. The basic guideline for a service provider to generate FD_QOS/FD_GROUP_QOS notifications is when the current level of service supported is significantly different (especially, in the negative direction) from what was last reported. The client should use WSPIoctl with SIO_GET_QOS and/or SIO_GET_GROUP_QOS to retrieve the corresponding FLOWSPEC structures and examine them in order to discover what aspect of the service level has changed. Note that the QUALITYOFSERVICE structures should be updated as appropriate regardless of whether FD_QOS/FD_GROUP_QOS is registered and generated. If the updated level of service is not acceptable, the client may adjust itself to accommodate it, attempt to renegotiate QOS, or close the socket. If a renegotiation is attempted, a successful return from the WSPIoctl function indicates that the revised QOS request was accepted, otherwise an appropriate error will be indicated.


SPI: Default Values

A default flow spec is associated with each eligible socket at the time it is created. Field values for this default flow spec are indicated below. In all cases these values indicate that no particular flow characteristics are being requested from the network. Applications only need to modify values for those fields which they are interested in, but must be aware that there exists some coupling between fields such as TokenRate and TokenBucketSize.

TokenRate          =  0xFFFFFFFF (not specified)
TokenBucketSize    =  0xFFFFFFFF (not specified)
PeakBandwidth      =  0xFFFFFFFF (not specified)
Latency            =  0xFFFFFFFF (not specified)
DelayVariation     =  0xFFFFFFFF (not specified)
ServiceType        =  SERVICETYPE_NOCHANGE
MaxSduSize         =  0xFFFFFFFF (not specified)
MinimumPolicedSize =  0xFFFFFFFF (not specified)


SPI: QOS Templates

Applications that don't want to deal with detailed QualityOfService structures directly and that utilize media types corresponding to well-known QOS template names can use WSPGetQOSByName to retrieve the detailed QualityOfService structure. For example, a video conferencing application which uses Indeo as its video codec and GSM as it audio codec may open two sockets, one for each media type, and get the detailed QualityOfService structure by calling WSPGetQOSByname with QOS_TEMPLATE_INDEO and QOS_TEMPLATE_GSM, respectively. Note that this function is implemented by the service provider associated with the specified socket descriptor, thus the QualityOfService structures returned is provider dependent, and may include a provider-specific part.

As new QOS template names become available, they need to be registered with the Windows Sockets 2 Clearing House. The documentation for WSPGetQOSByName will be periodically updated with a list of flow specifications and general descriptions as they become well-known. WSPGetQOSByName can also be used to enumerate the set of known QOS template names.


Socket Connections on Connection-Oriented Protocols

The following paragraphs describe the semantics applicable to socket connections over connection-oriented protocols.


Binding to a Local Address

Before a socket can be used to set up a connection or receive a connection request, it needs to be bound to a local address. This could be done explicitly by calling WSPBind, or implicitly by WSPConnect if the socket is unbound when this function is called.


The Basics: Listen, Connect, Accept

The basic operations involved with establishing a socket connection can be most conveniently explained in terms of the client-server paradigm.

The server side will first create a socket, bind it to a well known local address (so that the client can find it), and put the socket in listening mode, via WSPListen, in order to prepare for any incoming connection requests and to specify the length of the connection backlog queue. Service providers hold pending connection requests in a backlog queue until such time as they are acted upon by the server or are withdrawn (due to timeout) by the client. A service provider may silently ignore requests to extend the size of the backlog queue beyond a provider-defined upper limit.

At this point, if a blocking socket is being used, the server side may immediately call WSPAccept which will block until a connection request is pending. Conversely, the server may also use one of the network event indication mechanisms discussed previously to arrange for notification of incoming connection requests. Depending on the notification mechanism selected, the provider will either issue a Windows message or signal an event object when connection requests arrive. See section Notification of Network Events for how to register for the FD_ACCEPT network event.

The client side will create an appropriate socket, and initiate the connection by calling WSPConnect, specifying the known server address. Clients usually do not perform an explicit bind operation prior to initiating a connection, allowing the service provider to perform an implicit bind on their behalf. If the socket is in blocking mode, WSPConnect will block until the server has received and acted upon the connection request (or until a timeout occurs). Otherwise, the client should use one of the network event indication mechanisms discussed previously to arrange for notification of a new connection being established. Depending on the notification mechanism selected, the provider will indicate this either via a Windows message or by signaling an event object.

When the server side invokes WSPAccept, the service provider calls the application-supplied condition function, using function parameters to pass into the server information from the top entry in the connection request backlog queue. This information includes such things as address of connecting host, any available user data, and any available QOS information. Using this information the server's condition function determines whether to accept the request, reject the request or defer making a decision until later. This decision is indicated via the return value of the condition function. See section Notification of Network Events for how to register for the FD_CONNECT network event.

If the server decides to accept the request, the provider must create a new socket with all of the same attributes and event registrations as the listening socket. The original socket remains in the listening state so that subsequent connection requests can be received. Through output parameters of the condition function, the server may also supply any response user data, join the new socket to a new or existing socket group and assign QOS parameters (assuming that these operations are supported by the service provider).


Determining local and remote names

WSPGetSockName is used to retrieve the local address for bound sockets. This is especially useful when a WSPConnect call has been made without doing a WSPBind first; WSPGetSockName provides the only means to determine the local association which has been set implicitly by the provider.

After a connection has been setup, WSPGetPeerName can be used to determine the address of the peer to which a socket is connected.


Enhanced Functionality at Connect Time

Windows Sockets 2 offers an expanded set of operations that can occur coincident to establishing a socket connection. The service provider requirements for implementing these features are described below.

Conditional Acceptance

As described previously, WSPAccept invokes a client-supplied condition function that uses input parameters to supply information about the pending connection request. This information can be used by the client to accept or reject a connection request based on caller information such as caller ID, QOS, etc. If the condition function returns CF_ACCEPT, a new socket is created with the same properties as the listening socket, and a handle to the new socket is returned. If the condition function returns CF_REJECT, the connection request should be rejected. If the condition function returns CF_DEFER, the accept/reject decision cannot be made immediately, and the service provider must leave the connection request on the backlog queue. The client must call WSPAccept again, when it is ready to make a decision, and arrange for the condition function to return either CF_ACCEPT or CF_REJECT. While a deferred connection request is at the top of the backlog queue, the service provider does not issue any further indications for pending connection requests.

Exchanging User Data at Connect Time

Some protocols allow a small amount of user data to be exchanged at connect time. If such data has been received from the connecting host, it is placed in a service provider buffer, and a pointer to this buffer along with a length value are supplied to the Windows Sockets SPI client via input parameters to the WSPAccept condition function. If the Windows Sockets SPI client has response data to return to the connecting host, it may copy this into a buffer that is supplied by the service provider. A pointer to this buffer and an integer indicating buffer size are also supplied as condition function input parameters (if supported by the protocol).

Establishing Socket Groups

Note Reserved for future use with socket groups:

In the case of the condition function returning CF_ACCEPT, a new socket is created as mentioned above. Coincident with this socket creation, a socket group may be created or joined, depending on the value of output parameter g of the condition function. See WSPAccept for more information.


Connection Shutdown

The paragraphs which follow will describe operations incident to shutting down an established socket connection.

Initiating Shutdown Sequence

A socket connection can be taken down in one of several ways. WSPShutdown (with how equal to SD_SEND or SD_BOTH), and WSPSendDisconnect may be used to initiate a graceful connection shutdown. WSPCloseSocket can be used to initiate either a graceful or an abortive shutdown depending on the linger options as a side effect of closing a socket. See below for more information about graceful and abortive shutdown, and linger options.

Indicating Remote Shutdown

Service providers indicate connection teardown that is initiated by the remote party via the FD_CLOSE network event. Graceful shutdown is also be indicated via WSPRecv when the number of bytes read is 0 for byte-stream protocols, or via a return error code of WSAEDISCON for message-oriented protocols. In any case, a WSPRecv return error code of WSAECONNRESET indicates an abortive shutdown.

Exchanging User Data at Shutdown Time

At connection teardown time, it is also possible (for protocols that support this) to exchange user data between the endpoints. The end that initiates the teardown can call WSPSendDisconnect to indicate that no more data is to be sent and cause the connection teardown sequence to be initiated. For certain protocols, part of this teardown sequence is the delivery of disconnect data from the teardown initiator. After receiving notice that the remote end has initiated the teardown sequence (typically via the FD_CLOSE indication), the WSPRecvDisconnect function may be called to receive the disconnect data (if any).

To illustrate how disconnect data might be used, consider the following scenario. The client half of a client/server application is responsible for terminating a socket connection. Coincident with the termination it provides (via disconnect data) the total number of transactions it processed with the server. The server in turn responds back with the cumulative grand total of transactions that it has processed with all clients. The sequence of calls and indications might occur as follows:

Client Side | Server Side
(1) invoke WSPSendDisconnect to conclude session and supply transaction total |
 | (2) get FD_CLOSE, or WSPRecv with a return value of zero or WSAEDISCON indicating graceful shutdown in progress
 | (3) invoke WSPRecvDisconnect to get client's transaction total
 | (4) Compute cumulative grand total of all transactions
 | (5) invoke WSPSendDisconnect to transmit grand total
(6) receive FD_CLOSE indication | (5') invoke WSPClosesocket
(7) invoke WSPRecvDisconnect to receive and store cumulative grand total of transactions |
 | (8) invoke WSPClosesocket

Step (5') must follow step (5), but has no timing relationship with step (6), (7), or (8).

SPI: Graceful Shutdown, Linger Options and Socket Closure

It is important to distinguish the difference between shutting down a socket connection and closing a socket. Shutting down a socket connection involves an exchange of protocol messages between the two endpoints which is hereafter referred to as a shutdown sequence. Two general classes of shutdown sequences are defined: graceful and abortive (also referred to as "hard"). In a graceful shutdown sequence, any data that has been queued but not yet transmitted can be sent prior to the connection being closed. In an abortive shutdown, any unsent data is lost. The occurrence of a shutdown sequence (graceful or abortive) can also be used to provide an FD_CLOSE indication to the associated applications signifying that a shutdown is in progress. Closing a socket, on the other hand, causes the socket handle to become deallocated so that the application can no longer reference or use the socket in any manner.

In Windows Sockets, both the WSPShutdown function, and the WSPSendDisconnect function can be used to initiate a shutdown sequence, while the WSPCloseSocket function is used to deallocate socket handles and free up any associated resources. Some amount of confusion arises, however, from the fact that the WSPCloseSocket function will implicitly cause a shutdown sequence to occur if it has not already happened. In fact, it has become a rather common programming practice to rely on this feature and use WSPCloseSocket to both initiate the shutdown sequence and deallocate the socket handle.

To facilitate this usage, the sockets interface provides for controls via the socket option mechanism that allows the programmer to indicate whether the implicit shutdown sequence should be graceful or abortive, and also whether the WSPCloseSocket function should linger (i.e. not complete immediately) to allow time for a graceful shutdown sequence to complete.

By establishing appropriate values for the socket options SO_LINGER and SO_DONTLINGER, the following types of behavior can be obtained with the WSPCloseSocket function.

  • Abortive shutdown sequence, immediate return from WSPCloseSocket.
  • Graceful shutdown, delay return until either shutdown sequence completes or a specified time interval elapses. If the time interval expires before the graceful shutdown sequence completes, an abortive shutdown sequence occurs and WSPCloseSocket returns.
  • Graceful shutdown, return immediately and allow the shutdown sequence to complete in the background. This is the default behavior. Note, however, that the application has no way of knowing when (or whether) the graceful shutdown sequence completes.

One technique that can be used to minimize the chance of problems occurring during connection teardown is to not rely on an implicit shutdown being initiated by WSPCloseSocket. Instead one of the two explicit shutdown functions ( WSPShutdown or WSPSendDisconnect ) are used. This in turn will cause an FD_CLOSE indication to be received by the peer application indicating that all pending data has been received. To illustrate this, the following table shows the functions that would be invoked by the client and server components of an application, where the client is responsible for initiating a graceful shutdown.

Client Side | Server Side
(1) Invoke WSPShutdown(s, SD_SEND) to signal end of session and that client has no more data to send. |
 | (2) Receive FD_CLOSE, indicating graceful shutdown in progress and that all data has been received.
 | (3) Send any remaining response data.
(5') Get FD_READ and invoke recv to get any response data sent by server | (4) Invoke WSPShutdown(s, SD_SEND) to indicate server has no more data to send.
(5) Receive FD_CLOSE indication | (4') Invoke WSPCloseSocket
(6) Invoke WSPCloseSocket |

The timing sequence is maintained from step (1) to step (6) between the client and the server, except for step (4') and (5') which only has local timing significance in the sense that step (5) follows step (5') on the client side while step (4') follows step (4) on the server side, with no timing relationship with the remote party.


Socket Connections on Connectionless Protocols

The following sections describe the semantics of using connect operations on connectionless protocols such as UDP and IPX.


Connecting to a Default Peer

For a socket bound to a connectionless protocol, the operation performed by WSPConnect is merely to establish a default destination address so that the socket may be used with subsequent connection-oriented send and receive operations (WSPSend and WSPRecv). Any datagrams received from an address other than the destination address specified will be discarded.


Reconnecting and Disconnecting

The default destination may be changed by simply calling WSPConnect again, even if the socket is already "connected". Any datagrams queued for receipt are discarded if the new address is different from the address specified in a previous WSPConnect.

If the address supplied is all zeroes, the socket will be "dis-connected" - the default remote address will be indeterminate, so WSPSend and WSPRecv calls will return the error code WSAENOTCONN, although WSPSendTo and WSPRecvFrom may still be used.


Using sendto while connected

WSPSendTo will always deliver the data to the specifies address, even though a designated peer for the sending socket has been established in WSPConnect.


Socket I/O

There are three primary ways of doing I/O in Windows Sockets 2: blocking I/O, non-blocking I/O along with asynchronous notification of network events, and overlapped I/O with completion indication. We describe each method in the following sections. Blocking I/O is the default behavior, non-blocking mode can be utilized on any socket that is placed into non-blocking mode, and overlapped I/O can only occur on sockets that are created with the overlapped attribute. It is also interesting to note that the two calls for sending: WSPSend and WSPSendTo and the two calls for receiving: WSPRecv and WSPRecvFrom each implement all three methods of I/O. Service providers determine how to perform the I/O operation based on socket modes and attributes and the input parameter values.


Blocking I/O

The simplest form of I/O in Windows Sockets 2 is blocking I/O. As mentioned in section Socket Attribute Flags and Modes, sockets are created in blocking mode by default. Any I/O operation with a blocking socket will not return until the operation has been fully completed. Thus, any thread can only execute one I/O operation at a time. For example, if a thread issues a receive operation and no data is currently available, the thread will block until data becomes available and is placed into the thread's buffer. Although this is simple, it is not necessarily the most efficient way to do I/O in all versions of Windows. In Win16 environments for example, blocking is strongly discouraged due to the non-preemptive nature of the operating system (see section Pseudo vs. True Blocking for more information).


Non-Blocking I/O

If a socket is in a non-blocking mode, any I/O operation must either complete immediately or return error code WSAEWOULDBLOCK indicating that the operation cannot be finished right away. In the latter case, a mechanism is needed to discover when it is appropriate to try the operation again with the expectation that the operation shall succeed. A set of network events have been defined for this purpose and these can be polled or waited on by using WSPSelect, or be registered for asynchronous delivery by calling WSPAsyncSelect or WSPEventSelect. See section Notification of Network Events for more information.


Overlapped I/O

Windows Sockets 2 introduces overlapped I/O and requires that all transport providers support this capability. Overlapped I/O can be performed only on sockets that were created via the WSPSocket function with the WSA_FLAG_OVERLAPPED flag set, and follows the model established in Win32.

For receiving, a client uses WSPRecv or WSPRecvFrom to supply buffers into which data is to be received. If one or more buffers are posted prior to the time when data has been received by the network, it is possible that data will be placed into the user's buffers immediately as it arrives and thereby avoid the copy operation that would otherwise occur. If data is already present when receive buffers are posted, it is copied immediately into the user's buffers. If data arrives when no receive buffers have been posted by the application, the service provider resorts to the synchronous style of operation where the incoming data is buffered internally until such time as the client issues a receive call and thereby supplies a buffer into which the data may be copied. An exception to this would be if the application used WSPSetSockOpt to set the size of the receive buffer to zero. In this instance, reliable protocols would only allow data to be received when application buffers had been posted, and data on unreliable protocols would be lost.

On the sending side, clients use WSPSend or WSPSendTo to supply pointers to filled buffers and then agree to not disturb the buffers in any way until such time as the network has consumed the buffer's contents.

Overlapped send and receive calls return immediately. A return value of zero indicates that the I/O operation completed immediately and that the corresponding completion indication has already occurred. That is, the associated event object has been signaled, or the completion routine has been queued via WPUQueueApc. A return value of SOCKET_ERROR coupled with an error code of WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that a subsequent indication will be provided when send buffers have been consumed or when receive buffers are filled. Any other error code indicates that the overlapped operation was not successfully initiated and that no completion indication will be forthcoming.

Both send and receive operations can be overlapped. The receive functions may be invoked multiple times to post receive buffers in preparation for incoming data, and the send functions may be invoked multiple times to queue up multiple buffers to be sent. Note that while a series of overlapped send buffers will be sent in the order supplied, the corresponding completion indications may occur in a different order. Likewise, on the receiving side, buffers will be filled in the order they are supplied but the completion indications may occur in a different order.

The deferred completion feature of overlapped I/O is also available for WSPIoctl.

Delivering Completion Indications

Service providers have two ways to indicate overlapped completion: setting a client-specified event object, or invoking a client-specified completion routine. In both cases a data structure, WSAOVERLAPPED, is associated with each overlapped operation. This structure is allocated by the client and used by it to indicate which event object (if any) is to be set when completion occurs. The WSAOVERLAPPED structure may be used by the service provider as a place to store a "handle" to the results (e.g. number of bytes transferred, updated flags, error codes, etc.) for a particular overlapped operation. To obtain these results clients must invoke WSPGetOverlappedResult, passing in a pointer to the corresponding overlapped structure.

If event based completion indication is selected for a particular overlapped I/O request, the WSPGetOverlappedResult routine may itself be used by clients to either poll or wait for completion of the overlapped operation. If completion-routine-based completion indication is selected for a particular overlapped I/O request, only the polling option of WSPGetOverlappedResult is available. A client may also use other means to wait (such as using WSAWaitForMultipleEvents) until the corresponding event object has been signaled or the specified completion routine has been invoked by the service provider. Once completion has been indicated, the client may invoke WSPGetOverlappedResult, with the expectation that the call will complete immediately.

Invoking socket I/O completion routines

If the lpCompletionRoutine parameter to an overlapped operation is not NULL, it is the service provider's responsibility to arrange for invocation of the client-specified completion routine when the overlapped operation completes. Since the completion routine must be executed in the context of the same thread that initiated the overlapped operation, it cannot be invoked directly from the service provider. The WS2_32.DLL offers an asynchronous procedure call (APC) mechanism to facilitate invocation of completion routines.

A service provider arranges for a function to be executed in the proper thread by calling WPUQueueApc. This function can be called from any process and thread context, even a context different from the thread and process that was used to initiate the overlapped operation.

WPUQueueApc takes as input parameters a pointer to a WSATHREADID structure, a pointer to an APC function to be invoked, and a 32 bit context value that is subsequently passed to the APC function. Service providers are always supplied with a pointer to the proper WSATHREADID structure via the lpThreadId parameter to the overlapped function. The provider should store the WSATHREADID structure locally and supply a pointer to this copy of the WSATHREADID structure as an input parameter to WPUQueueApc. Once the WPUQueueApc function returns, the provider can dispose of its copy of the WSATHREADID.

The procedure WPUQueueApc simply enqueues sufficient information to call the indicated APC function with the given parameters, but does not call it. When the target thread enters an alertable wait state, this information is dequeued and a call is made to the APC function in that target thread and process context. Because the APC mechanism supports only a single 32 bit context value, the APC function cannot itself be the client-specified completion routine, which involves more parameters. The service provider must instead supply a pointer to its own APC function which uses the supplied context value to access the needed result information for the overlapped operation, and then invokes the client-specified completion routine.

For service providers where a user-mode component implements overlapped I/O a typical usage of the APC mechanism is as follows. When the I/O operation completes, the provider allocates a small buffer and packs it with a pointer to the client-supplied completion procedure and parameter values to pass to the procedure. It queues an APC, specifying the pointer to the buffer as the context value and its own intermediate procedure as the target procedure. When the target thread eventually enters alertable wait state, the service provider's intermediate procedure is called in the proper thread context. The intermediate procedure simply unpacks parameters, deallocates the buffer, and calls the client-supplied completion procedure.

For service providers where a kernel-mode component implements overlapped I/O a typical implementation is similar, except that the implementation would use standard kernel interfaces to enqueue the APC. Description of the relevant kernel interfaces is outside the scope of the Windows Sockets 2 specification.

Important Service providers must allow Windows Sockets 2 clients to invoke send and receive operations from within the context of the socket I/O completion routine, and guarantee that, for a given socket, I/O completion routines will not be nested.

Under some circumstances, a layered service provider may need to initiate and complete overlapped operations from within an internal worker thread. In this case, a WSATHREADID would not be available from an incoming function call. The service provider interface provides an upcall, WPUOpenCurrentThread, to obtain a WSATHREADID for the current thread. When this WSATHREADID is no longer needed, its resources should be returned by calling WPUCloseThread.

SPI: Summary of overlapped completion indication mechanisms

The following table summarizes the completion semantics for an overlapped socket, showing the various combination of lpOverlapped, hEvent, and lpCompletionRoutine:

lpOverlapped | hEvent | lpCompletionRoutine | Completion Indication
NULL | not applicable | ignored | Operation completes synchronously, i.e. it behaves as if it were a non-overlapped socket.
!NULL | NULL | NULL | Operation completes overlapped, but there is no Windows Sockets 2 supported completion mechanism. The completion port mechanism (if supported) may be used in this case, otherwise there will be no completion notification.
!NULL | !NULL | NULL | Operation completes overlapped, notification by signalling event object.
!NULL | ignored | !NULL | Operation completes overlapped, notification by scheduling completion routine.


SPI: Support for Scatter/Gather I/O

The WSPSend, WSPSendTo, WSPRecv, and WSPRecvFrom routines all take an array of client buffers as input parameters and thus may be used for scatter/gather (or vectored) I/O. This can be very useful in instances where portions of each message being transmitted consist of one or more fixed length "header" components in addition to a message body. Such header components need not be concatenated into a single contiguous buffer prior to sending. Likewise on receiving, the header components can be automatically split off into separate buffers, leaving the message body "pure".

Utilizing lists of buffers instead of a single buffer does not change the boundaries that apply to receive operations. For message-oriented protocols, a receive operation completes whenever a single message has been received, regardless of how many or few of the supplied buffers were utilized. Likewise for stream-oriented protocols, a receive completes when an unspecified quantity of bytes arrives over the network, not necessarily when all of the supplied buffers are full.


SPI: Out-Of-Band data

The service providers which support the out-of-band data abstraction for the stream-style sockets must adhere to the semantics in this section. We will describe OOB data handling in a protocol-independent manner. Please refer to the Windows Sockets 2 Protocol-Specific Annex (a separate document) for a discussion of OOB data implemented using "urgent data" in TCP/IP service providers. In the following, the use of WSPRecv also implies WSPRecvFrom.

SPI: Protocol Independent OOB data

OOB data is a logically independent transmission channel associated with each pair of connected stream sockets. OOB data may be delivered to the user independently of normal data. The abstraction defines that the OOB data facilities must support the reliable delivery of at least one OOB data block at a time. This data block may contain at least one byte of data, and at least one OOB data block may be pending delivery to the user at any one time. For communications protocols which support in-band signaling (i.e. TCP, where the "urgent data" is delivered in sequence with the normal data), the system normally extracts the OOB data from the normal data stream and stores it separately (leaving a gap in the "normal" data stream). This allows users to choose between receiving the OOB data in order and receiving it out of sequence without having to buffer all the intervening data. It is possible to "peek'' at out-of-band data.

A user can determine if there is any OOB data waiting to be read using the WSPIoctl(SIOCATMARK) function. For protocols where the concept of the "position" of the OOB data block within the normal data stream is meaningful (i.e. TCP), a Windows Sockets service provider will maintain a conceptual "marker" indicating the position of the last byte of OOB data within the normal data stream. This is not necessary for the implementation of the WSPIoctl(SIOCATMARK) functionality - the presence or absence of OOB data is all that is required.

For protocols where the concept of the "position" of the OOB data block within the normal data stream is meaningful an application may prefer to process out-of-band data "in-line", as part of the normal data stream. This is achieved by setting the socket option SO_OOBINLINE (see section WSPIoctl). For other protocols where the OOB data blocks are truly independent of the normal data stream, attempting to set SO_OOBINLINE will result in an error. An application can use the SIOCATMARK WSPIoctl command to determine whether there is any unread OOB data preceding the mark. For example, it might use this to resynchronize with its peer by ensuring that all data up to the mark in the data stream is discarded when appropriate.

With SO_OOBINLINE disabled (the default setting):

  • The Windows Sockets service provider notifies a client of an FD_OOB event, if the client registered for notification with WSPAsyncSelect, in exactly the same way FD_READ is used to notify of the presence of normal data. That is, FD_OOB is posted when OOB data arrives and there was no OOB data previously queued, and also when data is read using the MSG_OOB flag, and some OOB data remains to be read after the read operation has returned. FD_READ messages are not posted for OOB data.
  • The Windows Sockets service provider returns from WSPSelect with the appropriate exceptfds socket set if OOB data is queued on the socket.
  • the client can call WSPRecv with MSG_OOB to read the urgent data block at any time. The block of OOB data "jumps the queue".
  • the client can call WSPRecv without MSG_OOB to read the normal data stream. The OOB data block will not appear in the data stream with "normal data." If OOB data remains after any call to WSPRecv, the service provider notifies the client with FD_OOB or via exceptfds when using WSPSelect.
  • For protocols where the OOB data has a position within the normal data stream, a single WSPRecv operation will not span that position. One WSPRecv will return the normal data before the "mark", and a second WSPRecv is required to begin reading data after the "mark".

With SO_OOBINLINE enabled:

  • FD_OOB messages are _NOT_ posted for OOB data - for the purpose of the WSPSelect and WSPAsyncSelect functions, OOB data is treated as normal data, and indicated by setting the socket in readfds or by sending an FD_READ message respectively.
  • the client may not call WSPRecv with the MSG_OOB flag set to read the OOB data block - the error code WSAEINVAL will be returned.
  • the client can call WSPRecv without the MSG_OOB flag set. Any OOB data will be delivered in its correct order within the "normal" data stream. OOB data will never be mixed with normal data - there must be three read requests to get past the OOB data. The first returns the normal data prior to the OOB data block, the second returns the OOB data, the third returns the normal data following the OOB data. In other words, the OOB data block boundaries are preserved.

The WSPAsyncSelect routine is particularly well suited to handling notification of the presence of out-of-band-data when SO_OOBINLINE is off.


SPI: Shared Sockets

Socket sharing between processes in Windows Sockets is implemented as follows. A source process calls WSPDuplicateSocket to obtain a special WSAPROTOCOL_INFOW structure. It uses some interprocess communications (IPC) mechanism to pass the contents of this structure to a target process. The target process then uses the WSAPROTOCOL_INFOW structure in a call to WSPSocket. The socket descriptor returned by this function will be an additional socket descriptor to an underlying socket which thus becomes shared.

It is the service provider's responsibility to perform whatever operations are needed in the source process context and to create a WSAPROTOCOL_INFOW structure that will be recognized when it subsequently appears as a parameter to WSPSocket in the target processes' context. The dwProviderReserved field of the WSAPROTOCOL_INFOW struct is available for the service provider's use, and may be used to store any useful context information, including a duplicated handle.

This mechanism is designed to be appropriate for both single-threaded version of Windows (such as Windows 3.1) and preemptive multithreaded versions of Windows (such as Windows 95 and NT). Note however, that sockets may be shared amongst threads in a given process without using the WSPDuplicateSocket function, since a socket descriptor is valid in all of a process' threads.

As is described in section Descriptor Allocation, when new socket descriptors are allocated IFS providers must call WPUModifyIFSHandle and non-IFS providers must call WPUCreateSocketHandle.

One possible scenario for establishing and using a shared socket in a handoff mode is illustrated below:

Source Process | IPC | Destination Process
1) WSPSocket, WSPConnect |  |
2) Request target process ID | Þ |
 |  | 3) Receive process ID request and respond
4) Receive process ID | Ü |
5) Call WSPDuplicateSocket to get a special WSAPROTOCOL_INFOW structure |  |
6) Send WSAPROTOCOL_INFOW structure to target |  |
 | Þ | 7) Receive WSAPROTOCOL_INFOW structure
 |  | 8) Call WSPSocket to create shared socket descriptor.
10) WSPClosesocket |  | 9)Use shared socket for data exchange


Multiple Handles to a Single Socket

Since what is duplicated are the socket descriptors and not the underlying socket, all of the state associated with a socket is held in common across all the descriptors. For example a WSPSetSockOpt operation performed using one descriptor is subsequently visible using a WSPGetSockOpt from any or all descriptors.

Notification on shared sockets is subject to the usual constraints of WSPAsyncSelect and WSPEventSelect. Issuing either of these calls using any of the shared descriptors cancels any previous event registration for the socket, regardless of which descriptor was used to make that registration. Thus, for example, it would not be possible to have process A receive FD_READ events and process B receive FD_WRITE events. For situations when such tight coordination is required, it is suggested that developers consider using threads instead of separate processes.


Reference Counting

A process may call WSPCloseSocket on a duplicated socket and the descriptor will become deallocated. The underlying socket, however, will remain open until WSPCloseSocket is called on the last remaining descriptor.


Precedence Guidelines

The two (or more) descriptors that reference a shared socket may be used independently as far as I/O is concerned. However, the Windows Sockets interface does not implement any type of access control, so it is up to the processes involved to coordinate their operations on a shared socket. A typical use for shared sockets is to have one process that is responsible for creating sockets and establishing connections, hand off sockets to other processes which are responsible for information exchange.

The general guideline for supporting multiple outstanding operations on shared sockets is that a service provider is encouraged to honor all simultaneous operations on shared sockets, especially the most recent operation on a socket object. If need be, this may occur at the expense of aborting some of the previous but still pending operations, which will return WSAEINTR in this case.


SPI: Protocol-Independent Multicast and Multipoint

Just as Windows Sockets 2 allows the basic data transport capabilities of numerous transport protocols to be accessed in a generic manner, it also provides a generic way to utilize multipoint and multicast capabilities of transports that implement these features. To simplify, the term multipoint is used hereafter to refer to both multicast and multipoint communications.

Current multipoint implementations (e.g. IP multicast, ST-II, T.120, ATM UNI, etc.) vary widely with respect to how nodes join a multipoint session, whether a particular node is designated as a central or root node, and whether data is exchanged between all nodes or only between a root node and the various leaf nodes. Windows Sockets 2's WSAPROTOCOL_INFOW struct is used to declare the various multipoint attributes of a protocol. By examining these attributes the programmer will know what conventions to follow in utilizing the applicable Windows Sockets 2 functions to setup, utilize and teardown multipoint sessions.

The features of Windows Sockets 2 that support multicast can be summarized as follows:

  • Three attribute bits in the WSAPROTOCOL_INFOW struct
  • Four flags defined for the dwFlags parameter of WSPSocket
  • One function, WSPJoinLeaf, for adding leaf nodes into a multipoint session
  • Two WSPIoctl command codes for controlling multipoint loopback and establishing the scope for multicast transmissions. (The latter corresponds to the IP multicast time-to-live or TTL parameter.)

Note The inclusion of these multipoint features in Windows Sockets 2 does not preclude a service provider from also supporting an existing protocol-dependent interface, such as the Deering socket options for IP multicast.


Multipoint Taxonomy and Glossary

The taxonomy described below first distinguishes the control plane that concerns itself with the way a multipoint session is established, from the data plane that deals with the transfer of data amongst session participants.

In the control plane, there are two distinct types of session establishment: rooted and non-rooted. In the case of rooted control, there exists a special participant, called c_root, that is different from the rest of the members of this multipoint session, each of which is called a c_leaf. The c_root must remain present for the whole duration of the multipoint session, as the session will be broken up in the absence of the c_root. The c_root usually initiates the multipoint session by setting up the connection to a c_leaf, or a number of c_leafs. The c_root may add more c_leafs, or (in some cases) a c_leaf can join the c_root at a later time. Examples of the rooted control plane can be found in ATM and ST-II.

For a non-rooted control plane, all the members belonging to a multipoint session are leaves, i.e., no special participant acting as a c_root exists. Each c_leaf needs to add itself to a pre-existing multipoint session that either is always available (as in the case of an IP multicast address), or has been set up through some out-of-band mechanism which is outside the scope of this discussion (and hence not addressed in the proposed Windows Sockets extensions). Another way to look at this is that a c_root still exists, but can be considered to be in the network cloud as opposed to one of the participants. Because a control root still exists, a non-rooted control plane could also be considered to be implicitly rooted. Examples for this kind of implicitly rooted multipoint schemes are: a teleconferencing bridge, the IP multicast system, a Multipoint Control Unit (MCU) in a H.320 video conference, etc.

In the data plane, there are also two types of data transfer styles: rooted and non-rooted. In a rooted data plane, a special participant called d_root exists. Data transfer only occurs between the d_root and the rest of the members of this multipoint session, each of which is referred to as a d_leaf. The traffic could be uni-directional, or bi-directional. The data sent out from the d_root will be duplicated (if required) and delivered to every d_leaf, while the data from d_leafs will only go to the d_root. In the case of a rooted data plane, there is no traffic allowed among d_leafs. An example of a protocol that is rooted in the data plane is ST-II.

In a non-rooted data plane, all the participants are equal in the sense that any data they send will be delivered to all the other participants in the same multipoint session. Likewise each d_leaf node will be able to receive data from all other d_leafs, and in some cases, from other nodes which are not participating in the multipoint session as well. No special d_root node exists. IP-multicast is non-rooted in the data plane.

Note that the question of where data unit duplication occurs, or whether a shared single tree or multiple shortest-path trees are used for multipoint distribution are protocol issues, and are irrelevant to the interface the client would use to perform multipoint communications. Therefore these issues are not addressed by the Windows Sockets interface.

The following table depicts the taxonomy described above and indicates how existing schemes fit into each of the categories. Note that there does not appear to be any multipoint schemes that employ a non-rooted control plane along with a rooted data plane.

 | rooted control plane | non-rooted (implicit rooted) control plane
rooted data plane | ATM, ST-II | No known examples
non-rooted data plane | T.120 | IP-multicast, H.320 (MCU)


Multipoint attributes in WSAPROTOCOL_INFO structure

Multipoint attributes in WSAPROTOCOL_INFOW structure

Three attribute fields are defined in the WSAPROTOCOL_INFOW structure in order to distinguish the different schemes used in the control and data planes respectively:

  1. XP1_SUPPORT_MULTIPOINT with a value of 1 indicates this protocol entry supports multipoint communications, and that the following two fields are meaningful.
  2. XP1_MULTIPOINT_CONTROL_PLANE indicates whether the control plane is rooted (value = 1) or non-rooted (value = 0).
  3. XP1_MULTIPOINT_DATA_PLANE indicates whether the data plane is rooted (value = 1) or non-rooted (value = 0).

Two WSAPROTOCOL_INFOW entries would be present if a multipoint protocol supported both rooted and non-rooted data planes, one entry for each.


Multipoint Socket Attributes

In some instances sockets joined to a multipoint session may have some behavioral differences from point-to-point sockets. For example, a d_leaf socket in a rooted data plane scheme can only send information to the d_root participant. This creates a need for the client to be able to indicate the intended use of a socket coincident with its creation. This is done through four multipoint attribute flags that can be set via the dwFlags parameter in WSPSocket:

  • WSA_FLAG_MULTIPOINT_C_ROOT, for the creation of a socket acting as a c_root, and only allowed if a rooted control plane is indicated in the corresponding WSAPROTOCOL_INFOW entry.
  • WSA_FLAG_MULTIPOINT_C_LEAF, for the creation of a socket acting as a c_leaf, and only allowed if XP1_SUPPORT_MULTIPOINT is indicated in the corresponding WSAPROTOCOL_INFOW entry.
  • WSA_FLAG_MULTIPOINT_D_ROOT, for the creation of a socket acting as a d_root, and only allowed if a rooted data plane is indicated in the corresponding WSAPROTOCOL_INFOW entry.
  • WSA_FLAG_MULTIPOINT_D_LEAF, for the creation of a socket acting as a d_leaf, and only allowed if XP1_SUPPORT_MULTIPOINT is indicated in the corresponding WSAPROTOCOL_INFOW entry.

When creating a multipoint socket, exactly one of the two control plane flags, and one of the two data plane flags must be set in WSPSocket's dwFlags parameter. Thus, the four possibilities for creating multipoint sockets are: "c_root/d_root", "c_root/d_leaf", "c_leaf/d_root", or "c_leaf /d_leaf".


SIO_MULTIPOINT_LOOPBACK ioctl

When d_leaf sockets are used in a non-rooted data plane, it is generally desirable to be able to control whether traffic sent out is also received back on the same socket. The SIO_MULTIPOINT_LOOPBACK command code for WSPIoctl is used to enable or disable loopback of multipoint traffic.


SIO_MULTICAST_SCOPE ioctl

When multicasting is employed, it is usually necessary to specify the scope over which the multicast should occur. Here scope is defined to be the number of routed network segments to be covered. The SIO_MULTICAST_SCOPE command code for WSPIoctl is used to control this. A scope of zero would indicate that the multicast transmission would not be placed "on the wire" but could be disseminated across sockets within the local host. A scope value of one (the default) indicates that the transmission will be placed on the wire, but will not cross any routers. Higher scope values determine the number of routers that may be crossed. Note that this corresponds to the time-to-live (TTL) parameter in IP multicasting.


SPI: Semantics for joining multipoint leaves

In the following, a multipoint socket is frequently characterized by describing its role in one of the two planes (control or data). It should be understood that this same socket has a role in the other plane, but this is not mentioned in order to keep the references short. For example a reference to a "c_root socket" could refer to either a c_root/d_root or a c_root/d_leaf socket.

In rooted control plane schemes, new leaf nodes are added to a multipoint session in one or both of two different ways. In the first method, the root uses WSPJoinLeaf to initiate a connection with a leaf node and invite it to become a participant. On the leaf node, the peer application must have created a c_leaf socket and used WSPListen to set it into listen mode. The leaf node will receive an FD_ACCEPT indication when invited to join the session, and signals its willingness to join by calling WSPAccept. The root application will receive an FD_CONNECT indication when the join operation has been completed.

In the second method, the roles are essentially reversed. The root client creates a c_root socket and sets it into listen mode. A leaf node wishing to join the session creates a c_leaf socket and uses WSPJoinLeaf to initiate the connection and request admittance. The root client receives FD_ACCEPT when an incoming admittance request arrives, and admits the leaf node by calling WSPAccept. The leaf node receives FD_CONNECT when it has been admitted.

In a non-rooted control plane, where all nodes are c_leaf's, the WSPJoinLeaf function is used to initiate the inclusion of a node into an existing multipoint session. An FD_CONNECT indication is provided when the join has been completed and the returned socket descriptor is useable in the multipoint session. In the case of IP multicast, this would correspond to the IP_ADD_MEMBERSHIP socket option.

There are, therefore, three instances where a client would use WSPJoinLeaf:

  1. Acting as a multipoint root and inviting a new leaf to join the session
  2. Acting as a leaf making an admittance request to a rooted multipoint session
  3. Acting as a leaf seeking admittance to a non-rooted multipoint session (e.g. IP multicast)


Using WSPJoinLeaf

As mentioned previously, WSPJoinLeaf is used to join a leaf node into a multipoint session. WSPJoinLeaf has the same parameters and semantics as WSPConnect except that it returns a socket descriptor (as in WSPAccept), and it has an additional dwFlags parameter. The dwFlags parameter is used to indicate whether the socket will be acting only as a sender, only as a receiver, or both. Only multipoint sockets may be used for input parameter s in this function. If the multipoint socket is in the non-blocking mode, the returned socket descriptor will not be useable until after a corresponding FD_CONNECT indication has been received. A root application in a multipoint session may call WSPJoinLeaf one or more times in order to add a number of leaf nodes, however at most one multipoint connection request may be outstanding at a time.

The socket descriptor returned by WSPJoinLeaf is different depending on whether the input socket descriptor, s, is a c_root or a c_leaf. When used with a c_root socket, the name parameter designates a particular leaf node to be added and the returned socket descriptor is a c_leaf socket corresponding to the newly added leaf node. It is not intended to be used for exchange of multipoint data, but rather is used to receive network event indications (e.g. FD_CLOSE) for the connection that exists to the particular c_leaf. Some multipoint implementations may also allow this socket to be used for "side chats" between the root and an individual leaf node. An FD_CLOSE indication should be given for this socket if the corresponding leaf node calls WSPCloseSocket to drop out of the multipoint session. Symmetrically, invoking WSPClosesocket on the c_leaf socket returned from WSPJoinLeaf will cause the socket in the corresponding leaf node to get FD_CLOSE notification.

When WSPJoinLeaf is invoked with a c_leaf socket, the name parameter contains the address of the root application (for a rooted control scheme) or an existing multipoint session (non-rooted control scheme), and the returned socket descriptor is the same as the input socket descriptor. In a rooted control scheme, the root client would put its c_root socket in the listening mode by calling WSPListen. The standard FD_ACCEPT notification will be delivered when the leaf node requests to join itself to the multipoint session. The root client uses the usual WSPAccept function to admit the new leaf node. The value returned from WSPAccept is also a c_leaf socket descriptor just like those returned from WSPJoinLeaf. To accommodate multipoint schemes that allow both root-initiated and leaf-initiated joins, it is acceptable for a c_root socket that is already in listening mode to be used as in input to WSPJoinLeaf.

A multipoint root client is generally responsible for the orderly dismantling of a multipoint session. Such an application may use WSPShutdown or WSPClosesocket on a c_root socket to cause all of the associated c_leaf sockets, including those returned from WSPJoinLeaf and their corresponding c_leaf sockets in the remote leaf nodes, to get FD_CLOSE notification.


SPI: Semantic differences between multipoint sockets and regular sockets

In the control plane, there are some significant semantic differences between a c_root socket and a regular point-to-point socket:

  1. the c_root socket can be used in WSPJoinLeaf to join a new a leaf;
  2. placing a c_root socket into the listening mode (by callings WSPListen) does not preclude the c_root socket from being used in a call to WSPJoinLeaf to add a new leaf, or for sending and receiving multipoint data;
  3. the closing of a c_root socket will cause all the associated c_leaf sockets to get FD_CLOSE notification.

There is no semantic differences between a c_leaf socket and a regular socket in the control plane, except that the c_leaf socket can be used in WSPJoinLeaf, and the use of c_leaf socket in WSPListen indicates that only multipoint connection requests should be accepted.

In the data plane, the semantic differences between the d_root socket and a regular point-to-point socket are

  1. the data sent on the d_root socket will be delivered to all the leaves in the same multipoint session;
  2. the data received on the d_root socket may be from any of the leaves.

The d_leaf socket in the rooted data plane has no semantic difference from the regular socket, however, in the non-rooted data plane, the data sent on the d_leaf socket will go to all the other leaf nodes, and the data received could be from any other leaf nodes. As mentioned earlier, the information about whether the d_leaf socket is in a rooted or non-rooted data plane is contained in the corresponding WSAPROTOCOL_INFOW structure for the socket.


Socket Options and IOCTLs

The socket options for Winsock 2 are summarized in the following table. More detailed information is provided in section 4 under WSPGetSockOpt and/or WSPSetSockOpt. There are other new protocol-specific socket options which can be found in the protocol-specific annex.

A Windows Sockets service provider must recognize all of these options, and (for WSPGetSockOpt) return plausible values for each. The default value for each option is shown in the following table.

Value | Type | Meaning | Default | Note
SO_ACCEPTCONN | BOOL | Socket is WSPListening. | FALSE unless a WSPListen has been performed |
SO_BROADCAST | BOOL | Socket is configured for the transmission of broadcast messages. | FALSE |
SO_DEBUG | BOOL | Debugging is enabled. | FALSE | (i)
SO_DONTLINGER | BOOL | If true, the SO_LINGER option is disabled. | TRUE |
SO_DONTROUTE | BOOL | Routing is disabled. | FALSE | (i)
SO_ERROR | int | Retrieve error status and clear. | 0 |
SO_GROUP_ID | GROUP | Reserved for future use with socket groups. The identifier of the group to which this socket belongs. | NULL | get only
SO_GROUP _PRIORITY | int | Reserved for future use with socket groups. The relative priority for sockets that are part of a socket group. | 0 |
SO_KEEPALIVE | BOOL | Keepalives are being sent. | FALSE | (i)
SO_LINGER | struct linger | Returns the current linger options. | l_onoff is 0 |
SO_MAX_MSG _SIZE | int | Maximum outbound size of a message for message socket types. There is no provision to determine the maximum inbound message size. Has no meaning for stream-oriented sockets. | Implementation dependent | get only
SO_OOBINLINE | BOOL | Out-of-band data is being received in the normal data stream. | FALSE |
SO_PROTOCOL _INFOW | struct WSAPROTOCOL _INFOW | Description of protocol info for protocol that is bound to this socket. | protocol dependent | get only
SO_RCVBUF | int | Buffer size for receives | Implementation dependent | (i)
SO_REUSEADDR | BOOL | The address to which this socket is bound can be used by others. | FALSE |
SO_SNDBUF | int | Total per-socket buffer space reserved for sends. This is unrelated to SO_MAX_MSG _SIZE or the size of a TCP window. | Implementation dependent | (i)
SO_TYPE | int | The type of the socket (e.g. SOCK_STREAM). | As created via socket |
PVD_CONFIG | char FAR * | An opaque data structure object containing configuration information of the service provider. | Implementation dependent |
TCP_NODELAY | BOOL | Disables the Nagle algorithm for send coalescing. | Implementation dependent |
(i) A service provider may silently ignore this option on WSPSetSockOpt and return a constant value for WSPGetSockOpt, or it may accept a value for WSPSetSockOpt and return the corresponding value in WSPGetSockOpt without using the value in any way.


Summary of Socket Ioctl Opcodes

The socket ioctl opcodes for Winsock 2 are summarized in the following table. More detailed information is provided in section 4 under WSPIoctl. There are other new protocol-specific ioctl opcodes which can be found in the protocol-specific annex.

Opcode | Input Type | Output Type | Meaning
FIONBIO | unsigned long | <non used> | Enable or disable non-blocking mode on the socket.
FIONREAD | <not used> | unsigned long | Determine the amount of data which can be read atomically from the socket.
SIOCATMARK | <not used> | BOOL | Determine whether or not all out-of-band data has been read.
SIO_ASSOCIATE_HANDLE | companion API dependent | <not used> | Associate the socket with the specified handle of a companion interface.
SIO_ENABLE_CIRCULAR _QUEUEING | <not used> | <not used> | Circular queuing is enabled.
SIO_FIND_ROUTE | struct sockaddr | <not used> | Request the route to the specified address to be discovered.
SIO_FLUSH | <not used> | <not used> | Discard current contents of the sending queue.
SIO_GET_BROADCAST _ADDRESS | <not used> | struct sockaddr | Retrieve the protocol-specific broadcast address to be used in WSPSendTo.
SIO_GET_QOS | <not used> | QOS | Retrieve current flow spec(s) for the socket.
SIO_GET_GROUP_QOS | <not used> | QOS | Reserved for future use with socket groups; Retrieve current group flow spec(s) for the group this socket belongs to.
SIO_MULTIPOINT _LOOKBACK | BOOL | <not used> | Control whether data sent in a multipoint session will also be received by the same socket on the local host.
SIO_MULTICAST_SCOPE | int | <not used> | Specify the scope over which multicast transmissions will occur.
SIO_SET_QOS | QOS | <not used> | Establish new flow spec(s) for the socket.
SIO_SET_GROUP_QOS | QOS | <not used> | Reserved for future use with socket groups; Establish new group flow spec(s) for the group this socket belongs to.
SIO_TRANSLATE_HANDLE | int | companion API dependent | Obtain a corresponding handle for socket s that is valid in the context of a companion interface.
SIO_ROUTING_INTERFACE_QUERY | SOCKADDR | SOCKADDR | Obtain the address of local interface which should be used to send to the specified address
SIO_ROUTING_INTERFACE_CHANGE | SOCKADDR | <not used> | Request notification of changes in information reported via SIO_ROUTING_INTERFACE_QUERY for the specified address
SIO_ADDRESS_LIST_QUERY | <not used> | SOCKET_ADDRESS_LIST | Obtain the list of addresses to which application can bind.
SIO_ADDRESS_LIST_CHANGE | <not used> | <not used> | Request notification of changes in information reported via SIO_ADDRESS_LIST_QUERY
SIO_QUERY_PNP_TARGET_HANDLE | <not used> | SOCKET | Obtain socket descriptor of the next provider in the chain on which current socket depends in PnP sense


Summary of SPI Functions

The SPI functions for Winsock 2 are summarized in the following tables.


Generic Data Transport Functions

This section lists the Data Transport functions exposed by WS2SPI.H.

WSPAccept | An incoming connection is acknowledged and associated with an immediately created socket. The original socket is returned to the listening state. This function also allows for conditional acceptance and socket grouping.
WSPAsyncSelect | Perform asynchronous version of WSPSelect.
WSPBind | Assign a local name to an unnamed socket.
WSPCancelBlockingCall | Cancel an outstanding "blocking" Windows Sockets call.
WSPCleanup | Sign off from the underlying Windows Sockets service provider.
WSPCloseSocket | Remove a socket from the per-process object reference table. Only blocks if SO_LINGER is set with a non-zero timeout on a blocking socket.
WSPConnect | Initiate a connection on the specified socket. This function also allows for exchange of connect data and QOS specification.
WSPDuplicateSocket | Return a WSAPROTOCOL_INFOW structure that can be used to create a new socket descriptor for a shared socket.
WSPEnumNetworkEvents | Discover occurrences of network events.
WSPEventSelect | Associate network events with an event object.
WSPGetOverlappedResult | Get completion status of overlapped operation.
WSPGetPeerName | Retrieve the name of the peer connected to the specified socket.
WSPGetSockName | Retrieve the local address to which the specified socket is bound.
WSPGetSockOpt | Retrieve options associated with the specified socket.
WSPGetQOSByName | Supply QOS parameters based on a well-known service name.
WSPIoctl | Provide control for sockets.
WSPJoinLeaf | Join a leaf node into a multipoint session.
WSPListen | Listen for incoming connections on a specified socket.
WSPRecv | Receive data from a connected or unconnected socket. This function accommodates scatter/gather I/O, overlapped sockets and provides the flags parameter as IN OUT.
WSPRecvDisconnect | Terminate reception on a socket, and retrieve the disconnect data if the socket is connection-oriented.
WSPRecvFrom | Receive data from either a connected or unconnected socket. This function accommodates scatter/gather I/O, overlapped sockets and provides the flags parameter as IN OUT.
WSPSelect | Perform synchronous I/O multiplexing.
WSPSend | Send data to a connected socket. This function also accommodates scatter/gather I/O and overlapped sockets.
WSPSendDisconnect | Initiate termination of a socket connection and optionally send disconnect data.
WSPSendTo | Send data to either a connected or unconnected socket. This function also accommodates scatter/gather I/O and overlapped sockets.
WSPSetSockOpt | Store options associated with the specified socket.
WSPShutdown | Shut down part of a full-duplex connection.
WSPSocket | A socket creation function which takes a WSAPROTOCOL_INFOW struct as input and allows overlapped sockets to be created. Also allows socket groups to be formed.
WSPStartup | Initialize the underlying Windows Sockets service provider.


Upcalls exposed by Windows Sockets 2 DLL

This section lists the "upcalls" that service providers may make into the Windows Sockets client. Service providers receive an upcall dispatch table as a parameter to WSPStartup(), and use entries in this table to make the upcalls. Therefore, a client does not need to export its "WPU" functions.

It is not mandatory that providers utilize all of these upcalls. The following table indicates which upcalls must be used and which are optional.

This section describes the "upcalls" that service providers may make into the Windows Sockets client. Service providers receive an upcall dispatch table as a parameter to WSPStartup(), and use entries in this table to make the upcalls. Therefore, a client does not need to export its "WPU" functions.

It is not mandatory that providers utilize all of these upcalls. The following table indicates which upcalls must be used and which are optional.

WPUCloseEvent | Close an open event object handle | Optional. | The provider may use an appropriate OS call instead.
WPUCloseSocketHandle | Close a socket handle allocated by the Windows Sockets DLL | Required. | The WS2_32.DLLneeds to query and/or modify internal state information associated with the socket handle.
WPUCloseThread | Close a thread Id for an internal service thread |  |
WPUCompleteOverlappedRequest | Deliver overlapped I/O completion notification where the completion mechanism is something other than user mode APC |  |
WPUCreateEvent | Create a new event object | Optional | The provider may use an appropriate OS call instead.
WPUCreateSocketHandle | Create a new socket handle for non-IFS providers | Required for non-IFS providers. | The WS2_32.DLLneeds to query and/or modify internal state information associated with the socket handle.
WPUFDIsSet | Check the membership of the specified socket handle | Optional. | This is just a convenience function that knows how to dig through fd set structures. A provider may need to dig through these structures explicitly anyway.
WPUGetProviderPath | Retrieve the DLL path for the specified provider | Required. | Only the WS2_32.DLLwould know where an adjacent protocol layer (potentially from another vendor) has been installed.
WPUModifyIFSHandle | Receive a (possibly) modified IFS handle from the Windows Sockets DLL | Required for IFS providers. | The WS2_32.DLLneeds to query and/or modify internal state information associated with the socket handle.
WPUPostMessage | Performs the standard PostMessage function in a way that maintains backward compatibility | Required | NT only. Win95 allows post message from kernel mode.
WPUQueryBlockingCallback | Return a pointer to a thread's blocking hook function | Required | There is no corresponding OS functionality. Only the WS2_32.DLLhas the information to accomplish this.
WPUQuerySocketHandleContext | Get a socket's context value (non-IFS providers only) | Required for non-IFS providers. | The WS2_32.DLLneeds to query and/or modify internal state information associated with the socket handle.
WPUQueueApc | Queue a user-mode APC to the specified thread | Optional. | Win 32's QueueUserApc() may also be used.
WPUResetEvent | Reset an event object | Optional. | The provider may use an appropriate OS call instead.
WPUSetEvent | Set an event object | Optional. | The provider may use an appropriate OS call instead.


Installation and Configuration Functions

The following functions are implemented in the WS2_32.DLL, and are intended to be used by applications that install Windows Sockets transport and name space service providers on a machine. These functions neither affect currently running applications, nor are the changes made by these functions visible to currently running applications.

For all providers, a provider ID is a GUID which is generated by the developer of the provider (using the UUIDGEN.EXE utility) and supplied to WS2_32.DLL.

WSCDeinstallProvider | Unregister a service provider
WSCEnumProtocols | Retrieve information about available transport protocols
WSCInstallProvider | Register a new service provider


Name Resolution Service Provider Requirements

The following sections provide a description of each of the functional areas that name space providers are required to implement. Where appropriate, implementation considerations and guidelines are also provided.


Summary of Name Space Provider Functions

The name space service provider functions can be grouped into five categories: Name space provider configuration and installation, provider initialization, service installation, client queries, and helper functions (and macros). The sections that follow identify the functions in each category and briefly describe their intended use. Key data structures are also described.


Name Space Provider Configuration and Installation

WSCInstallNameSpace

WSCUnInstallNameSpace

WSCEnableNSProvider

As mentioned previously, the installation applet for a name space provider must call WSCInstallNameSpace to register with the WS2_32.DLL and supply static configuration information. The WS2_32.DLL uses this information to accomplish its routing function and in its implementation of WSAEnumNameSpaceProviders. The WSCUnInstallNameSpace function is used to de-register a name space provider, and the WSCEnableNSProvider function is used to toggle a provider between the active and inactive states.

The results of these three operations are not visible to applications that are currently loaded and running. Only applications that begin executing after these operations have occurred will be affected by them.

This architecture explicitly supports the instantiation of multiple name space providers within a single DLL, however each such provider must have a unique name space provider ID (GUID) allocated, and a separate call to WSCInstallNameSpace must occur for each instantiation. Such a provider can determine which instantiation is being invoked because the name space provider ID appears as a parameter in every NSP function.


Name Space Provider Initialization and Cleanup

NSPStartup

NSPCleanup

As is the case for the transport SPI, a name space provider is initialized with a call to NSPStartup and is terminated with a final call to NSPCleanup. Calls to the startup function may be nested, but will be matched by corresponding calls to the cleanup function. A provider should employ reference counting to determine when the final call to NSPCleanup has occurred.


SPI: Service Installation

NSPInstallServiceClass

NSPRemoveServiceClass

NSPSetService

When the required service class does not already exist, a name space SPI client uses NSPInstallServiceClass to install a new service class by supplying a service class name, a GUID for the service class ID, and a series of WSANSCLASSINFO structures. These structures are each specific to a particular name space, and supply common values such as recommended TCP port numbers or Netware SAP Identifiers. A service class can be removed by calling NSPRemoveServiceClass and supplying the GUID corresponding to the class ID.

Once a service class exists, specific instances of a service can be installed or removed via NSPSetService. This function takes a WSAQUERYSET structure as an input parameter along with an operation code and operation flags. The operation code indicates whether the service is being installed or removed. The WSAQUERYSET structure provides all of the relevant information about the service including service class ID, service name (for this instance), applicable name space identifier and protocol information, and a set of transport addresses at which the service listens.


Service Query

NSPLookupServiceBegin

NSPLookupServiceNext

NSPLookupServiceEnd

A name service query involves a series of calls: NSPLookupServiceBegin, followed by one or more calls to NSPLookupServiceNext and ending with a call to NSPLookupServiceEnd. NSPLookupServiceBegin takes a WSAQUERYSET structure as input in order to define the query parameters along with a set of flags to provide additional control over the search operation. It returns a query handle which is used in the subsequent calls to NSPLookupServiceNext and NSPLookupServiceEnd.

The name space SPI client invokes NSPLookupServiceNext to obtain query results, with results supplied in an client-supplied WSAQUERYSET buffer. The client continues to call NSPLookupServiceNext until the error code WSA_E_NO_MORE is returned indicating that all results have been retrieved. The search is then terminated by a call to NSPLookupServiceEnd. The NSPLookupServiceEnd function can also be used to cancel a currently pending NSPLookupServiceNext when called from another thread.

In Windows Sockets 2, conflicting error codes are defined for WSAENOMORE (10102) and WSA_E_NO_MORE (10110). The error code WSAENOMORE will be removed in a future version and only WSA_E_NO_MORE will remain. Name Space Providers should switch to using the WSA_E_NO_MORE error code as soon as possible to maintain compatibility with the widest possible range of applications.


SPI: Helper Functions

NSPGetServiceClassInfo

The NSPGetServiceClassInfo function retrieves service class schema information that has been retained by a name space provider. It is also used by the Winsock 2 DLL in its implementation of WSAGetServiceClassNameByServiceClassId.

The following macros from Winsock2.h are available and can aid in mapping between well known service classes and these name spaces.

SVCID_TCP(Port) SVCID_UDP(Port) SVCID_NETWARE(Object Type) | Given a port for TCP/IP or UDP/IP or the object type in the case of Netware, return the GUID
IS_SVCID_TCP(GUID) IS_SVCID_UDP(GUID) IS_SVCID_NETWARE(GUID) | Returns TRUE if the GUID is within the allowable range
PORT_FROM_SVCID_TCP(GUID) PORT_FROM_SVCID_UDP(GUID) SAPID_FROM_SVCID_NETWARE(GUID) | Returns the port or object type associated with the GUID


SPI: Name Resolution Data Structures

There are several important data structures that are used extensively throughout the name resolution functions. These are described below.


SPI: Windows Sockets 1.1 Compatibile Name Resolution for TCP/IP

Windows Sockets 1.1 defined a number of routines that were used for name resolution with TCP/IP networks. These are customarily called the getXbyY functions and include the following:

gethostname
gethostbyaddr
gethostbyname
getprotobyname
getprotobynumber
getservbyname
getservbyport

Asynchronous versions of these functions were also defined:

WSAAsyncGetHostByAddr
WSAAsyncGetHostByName
WSAAsyncGetProtoByName
WSAAsyncGetProtoByNumber
WSAAsyncGetServByName
WSAAsyncGetServByPort

These functions are specific to TCP/IP networks and developers of protocol-independent applications are discouraged from continuing to utilize these transport-specific functions. However, in order to retain strict backwards compatibility with Windows Sockets 1.1, all of the above functions continue to be supported as long as at least one name space provider is present that supports the AF_INET address family.

The WS2_32.DLL implements these compatibility functions in terms of the new, protocol-independent name resolution facilities using an appropriate sequence of WSALookupServiceBegin, WSALookupServiceNext, WSALookupServiceEnd function calls. The details of how the getXbyY functions are mapped to name resolution functions are provided below. The WS2_32.DLL handles the differences between the asynchronous and synchronous versions of the getXbyY functions, so only the implementation of the synchronous getXbyY functions are discussed.


SPI: Basic Approach for getxbyy

Most getXbyY functions are translated by WS2_32.DLL to a WSALookupServiceBegin, WSALookupServiceNext, WSALookupServiceEnd sequence that uses one of a set of special GUIDs as the service class. These GUIDs identify the type of getXbyYoperation that is being emulated. The query is constrained to those NSPs that support AF_INET. Whenever a getXbyY function returns a hostent or servent structure, the WS2_32.DLL will specify the LUP_RETURN_BLOB flag in WSALookupServiceBegin so that the desired information will be returned by the NSP. These structures must be modified slightly in that the pointers contained within must be replaced with offsets that are relative to the start of the blob's data. All values referenced by these pointer fields must, of course, be completely contained within the blob, and all strings are ASCII.


SPI: The getprotobyname and getprotobynumber functions

These functions are implemented within WS2_32.DLL by consulting a local protocols database. They do not result in any name resolution query.


SPI: The getservbyname and getservbyport functions

The WSALookupServiceBegin query uses SVCID_INET_SERVICEBYNAME as the service class GUID. The lpszServiceInstanceName field references a string which indicates the service name or service port, and (optionally) the service protocol. The formatting of the string is illustrated as "ftp/tcp" or "21/tcp" or just "ftp". The string is not case sensitive. The slash mark, if present, separates the protocol identifier from the preceding part of the string. The WS2_32.DLL will specify LUP_RETURN_BLOB and the NSP will place a servent struct in the blob (using offsets instead of pointers as described above). NSPs should honor these other LUP_RETURN_* flags as well:

LUP_RETURN_NAME | return the s_name field from servent struct in lpszServiceInstanceName.
LUP_RETURN_TYPE | return canonical GUID in lpServiceClassId It is understood that a service identified either as "ftp" or "21" may in fact be on some other port according to locally established conventions. The s_port field of the servent structure should indicate where the service can be contacted in the local environment. The canonical GUID returned when LUP_RETURN_TYPE is set should be one of the predefined GUIDs from svcs.h that corresponds to the port number indicated in the servent structure.


SPI: The gethostbyname function

The WSALookupServiceBegin query uses SVCID_INET_HOSTADDRBYNAME as the service class GUID. The host name is supplied in lpszServiceInstanceName. The WS2_32.DLL specifies LUP_RETURN_BLOB and the NSP places a hostent struct in the blob (using offsets instead of pointers as described above). NSPs should honor these other LUP_RETURN_* flags as well:

LUP_RETURN_NAME | return the h_name field from hostent struct in lpszServiceInstanceName.
LUP_RETURN_ADDR | return addressing info from hostent in CSADDR_INFO structs, port information is defaulted to zero. Note that this routine does not resolve host names that consist of a dotted internet address.


SPI: The gethostbyaddr function

The WSALookupServiceBegin query uses SVCID_INET_HOSTNAMEBYADDR as the service class GUID. The host address is supplied in lpszServiceInstanceName as a dotted internet string (e.g. "192.9.200.120"). The WS2_32.DLL specifies LUP_RETURN_BLOB and the NSP places a hostent struct in the blob (using offsets instead of pointers as described above). NSPs should honor these other LUP_RETURN_* flags as well:

LUP_RETURN_NAME | return the h_name field from hostent struct in lpszServiceInstanceName.
LUP_RETURN_ADDR | return addressing info from hostent in CSADDR_INFO structs, port information is defaulted to zero.


SPI: The gethostname function

The WSALookupServiceBegin query uses SVCID_HOSTNAME as the service class GUID. If lpszServiceInstanceName is NULL or references a NULL string (that is . ""), the local host is to be resolved. Otherwise, a lookup on a specified host name shall occur. For the purposes of emulating gethostname the WS2_32.DLL will specify a null pointer for lpszServiceInstanceName, and specify LUP_RETURN_NAME so that the host name is returned in the lpszServiceInstanceName field. If an application uses this query and specifies LUP_RETURN_ADDR then the host address will be provided in a CSADDR_INFO struct. The LUP_RETURN_BLOB action is undefined for this query. Port information will be defaulted to zero unless the lpszQueryString references a service such as "ftp", in which case the complete transport address of the indicated service will be supplied.


Sample code for a Service Provider

This section contains a source code sample that demonstrates how to implement the GetXbyY functions using the new, protocol-independent RNR functions. A developer should implement these functions as a starting point. To comply with the Windows Sockets specification, many more functions are needed.

Important The following code is not guaranteed to compile.

/*++
    xbyrnr.cpp

    Copyright (c) 1996 Microsoft Corporation
    All rights reserved

    GetXbyY emulation via new WinSock2 RNR. This source module shows
    code that is built into the WinSock2 DLL (ws2_32.dll). It
    demonstrates how the older GetXByY functions are mapped to the new
    WSALookupServiceBegin, WSALookupServiceNext, WSALookupServiceEnd
    functions.

    This module is not guaranteed to compile. It is provided as source
    code for RNR name-space service providers to understand what will
    be coming down to their code in response to the traditional
    GetXbyY calls.

    At this time, only
        gethostname
        gethostbyname
        gethostbyaddr
        getservbyname
        getservbyport
    are implemented in this manner.

    Warning:  This code is preliminary, and may change before Windows
    Sockets 2 is released.

    Warning: This is not provided as a template for either RNR
    applications or name space providers. This code is only intended
    to illustrate what happens in the WinSock2 DLL to map the GetXbyY
    calls to the new RNR APIs.
--*/

#include "svcguid.h"

//
//  Forward declares
//

LPBLOB
getxyDataEnt(
    PCHAR  pResults,
    DWORD  dwSize,
    LPSTR lpszName,
    LPGUID lpType,
    LPSTR *  lppName
    );

VOID
FixList(PCHAR ** List, PCHAR Base);

VOID
UnpackHostEnt(struct hostent * hostent);

VOID
UnpackServEnt(struct servent * servent);

GUID HostnameGuid = SVCID_INET_HOSTADDRBYNAME;
GUID AddressGuid =  SVCID_INET_HOSTADDRBYINETSTRING;
GUID IANAGuid    =  SVCID_INET_SERVICEBYNAME;

//
// Utility to turn a list of offsets into a list of addresses. Used
// to convert structures returned as BLOBs.
//

VOID
FixList(PCHAR ** List, PCHAR Base)
{
    if(*List)
    {
        PCHAR * Addr;

        Addr = *List = (PCHAR *)( ((DWORD)*List + Base) );
        while(*Addr)
        {
            *Addr = (PCHAR)(((DWORD)*Addr + Base));
            Addr++;
        }
    }
}

//
// Routine to convert a hostent returned in a BLOB to one with
// usable pointers. The structure is converted in-place.
//
VOID
UnpackHostEnt(struct hostent * hostent)
{
     PCHAR pch;

     pch = (PCHAR)hostent;

     if(hostent->h_name)
     {
         hostent->h_name = (PCHAR)((DWORD)hostent->h_name + pch);
     }
     FixList(&hostent->h_aliases, pch);
     FixList(&hostent->h_addr_list, pch);
}

//
// Routine to unpack a servent returned in a BLOB to one with
// usable pointers. The structure is converted in-place
//

VOID
UnpackServEnt(struct servent * servent)
{
    PCHAR pch;

    pch = (PCHAR)servent;

    FixList(&servent->s_aliases, pch);
    servent->s_name = (PCHAR)(DWORD(servent->s_name) + pch);
    servent->s_proto = (PCHAR)(DWORD(servent->s_proto) + pch);
}

struct hostent FAR * WSAAPI
gethostbyaddr(
    IN const char FAR * addr,
    IN int len,
    IN int type
    )
/*++
Routine Description:

    Get host information corresponding to an address.

Arguments:

    addr - A pointer to an address in network byte order.

    len - The length of the address, which must be 4 for PF_INET
    addresses.

    type - The type of the address, which must be PF_INET.

Returns:

    If no error occurs, gethostbyaddr() returns a pointer to the
    hostent structure described above. Otherwise it returns a NULL
    pointer and a specific error code is stored with SetErrorCode().
--*/
{
    CHAR qbuf[100];
    struct hostent *ph;
    LPBLOB pBlob;
    PCHAR pResults;
    int err, ErrorCode;
    PDPROCESS Process;
    PDTHREAD Thread;

    err = PROLOG(&Process,
                   &Thread,
                    &ErrorCode);
    if(err != NO_ERROR)
    {
        SetLastError(ErrorCode);
        return(NULL);
    }

    pResults = new CHAR[RNR_BUFFER_SIZE];

    if(!pResults)
    {
        SetLastError(WSA_NOT_ENOUGH_MEMORY);
        return(NULL);
    }

    //
    // NOTICE. Only handles current inet address forms.
    //
    (void)wsprintfA(qbuf, "%u.%u.%u.%u",
            ((unsigned)addr[0] & 0xff),
            ((unsigned)addr[1] & 0xff),
            ((unsigned)addr[2] & 0xff),
            ((unsigned)addr[3] & 0xff));

    pBlob = getxyDataEnt(pResults,
                         RNR_BUFFER_SIZE,
                         qbuf,
                         &AddressGuid,
                         0);
    if(pBlob)
    {
        ph = (struct hostent *)Thread->CopyHostEnt(pBlob);
        if(ph)
        {
            UnpackHostEnt(ph);
        }
    }
    else
    {
        ph = 0;
        if(GetLastError() == WSASERVICE_NOT_FOUND)
        {
            SetLastError(WSANO_ADDRESS);
        }
    }
    delete pResults;
    return(ph);
}  // gethostbyaddr

struct hostent FAR * WSAAPI
gethostbyname(
    IN const char FAR * name
    )
/*++
Routine Description:

    Get host information corresponding to a hostname.

Arguments:

    name - A pointer to the null terminated name of the host.

Returns:

    If no error occurs, gethostbyname() returns a pointer to the
    hostent structure described above. Otherwise it returns a NULL
    pointer and a specific errorr code is stored with SetErrorCode().
--*/
{
    struct hostent * hent;
    LPBLOB pBlob;
    PCHAR pResults;
    int err, ErrorCode;
    PDPROCESS Process;
    PDTHREAD Thread;
    CHAR  szLocalName[200];   // for storing the local name. This
                              // is simply a big number assumed
                              // to be large enough. This is used
                              // only when the caller chooses not to
                              // provide a name.
    PCHAR pszName;

    err = PROLOG(&Process,
                 &Thread,
                 &ErrorCode);
    if(err != NO_ERROR)
    {
        SetLastError(ErrorCode);
        return(NULL);
    }

    //
    // A NULL input name means look for the local name. So,
    // get it.
    //
    if(!name || !*name)
    {
        if(gethostname(szLocalName, 200) != NO_ERROR)
        {
            return(NULL);
        }
        pszName = szLocalName;
    }
    else
    {
        pszName = (PCHAR)name;
    }

    pResults = new CHAR[RNR_BUFFER_SIZE];

    if(!pResults)
    {
        SetLastError(WSA_NOT_ENOUGH_MEMORY);
        return(NULL);
    }

    pBlob = getxyDataEnt( pResults,
                          RNR_BUFFER_SIZE,
                          pszName,
                          &HostnameGuid,
                          0);
    if(pBlob)
    {
        hent = (struct hostent *)Thread->CopyHostEnt(pBlob);
        if(hent)
        {
            UnpackHostEnt(hent);
        }
    }
    else
    {
        hent = 0;
        if(GetLastError() == WSASERVICE_NOT_FOUND)
        {
            SetLastError(WSAHOST_NOT_FOUND);
        }
    }
    delete pResults;
    return(hent);
}  // gethostbyname

int WSAAPI
gethostname(
    OUT char FAR * name,
    IN int namelen
    )
/*++
Routine Description:

    Return the standard host name for the local machine.

Arguments:

    name    - A pointer to a buffer that will receive the host name.

    namelen - The length of the buffer.

Returns:

    Zero on success else SOCKET_ERROR. The error code is stored with
    SetErrorCode().
--*/
{
    PCHAR lpName;
    int err, ErrorCode;
    PDPROCESS Process;
    PDTHREAD Thread;
    PCHAR pResults;

    err = PROLOG(&Process,
                   &Thread,
                    &ErrorCode);
    if(err != NO_ERROR)
    {
        SetLastError(ErrorCode);
        return(SOCKET_ERROR);
    }

    pResults = new CHAR[RNR_BUFFER_SIZE];

    if(!pResults)
    {
        SetLastError(WSA_NOT_ENOUGH_MEMORY);
        return(SOCKET_ERROR);
    }

    if(getxyDataEnt(pResults,
                    RNR_BUFFER_SIZE,
                    NULL,
                    &HostnameGuid,
                    &lpName
                    ))
    {
        INT iSize = strlen(lpName) + 1;

        if(iSize <= namelen)
        {
            memcpy(name, lpName, iSize);
        }
        else
        {
            SetLastError(WSAEFAULT);
            err = SOCKET_ERROR;
        }
    }
    else
    {
        err = SOCKET_ERROR;   // assume LastError has been set
    }
    delete pResults;
    return(err);
}  // gethostname

struct servent FAR * WSAAPI
getservbyport(
    IN int port,
    IN const char FAR * proto
    )
/*++
Routine Description:

    Get service information corresponding to a port and protocol.

Arguments:

    port  - The port for a service, in network byte order.

    proto - An optional pointer to a protocol name. If this is NULL,
            getservbyport() returns the first service entry for which
            the port matches the s_port. Otherwise getservbyport()
            matches both the port and the proto.

Returns:

    If no error occurs, getservbyport() returns a pointer to the
    servent structure described above. Otherwise it returns a NULL
    pointer and a specific error code is stored with SetErrorCode().
--*/
{
    PCHAR pszTemp;
    struct servent * sent;
    int err, ErrorCode;
    PDPROCESS Process;
    PDTHREAD Thread;
    LPBLOB pBlob;
    PCHAR pResults;

    err = PROLOG(&Process,
                   &Thread,
                    &ErrorCode);
    if(err != NO_ERROR)
    {
        SetLastError(ErrorCode);
        return(NULL);
    }

    pResults = new CHAR[RNR_BUFFER_SIZE];

    if(!pResults)
    {
        SetLastError(WSA_NOT_ENOUGH_MEMORY);
        return(NULL);
    }

    if(!proto)
    {
        proto = "";
    }

    //
    // the 5 is the max number of digits in a port
    //
    pszTemp = new CHAR[strlen(proto) + 1 + 1 + 5];
    wsprintfA(pszTemp, "%d/%s", (port & 0xffff), proto);
    pBlob =  getxyDataEnt(pResults,
                          RNR_BUFFER_SIZE,
                          pszTemp,
                          &IANAGuid,
                          0
                          );
    delete pszTemp;
    if(!pBlob)
    {
        sent = 0;
        if(GetLastError() == WSATYPE_NOT_FOUND)
        {
            SetLastError(WSANO_DATA);
        }
    }
    else
    {
        sent = (struct servent *)Thread->CopyServEnt(pBlob);
        if(sent)
        {
            UnpackServEnt(sent);
        }
    }
    delete pResults;
    return(sent);
}  // getservbyport

struct servent FAR * WSAAPI
getservbyname(
    IN const char FAR * name,
    IN const char FAR * proto
    )
/*++
Routine Description:

    Get service information corresponding to a service name and
    protocol.

Arguments:

     name  - A pointer to a null terminated service name.

    proto - An optional pointer to a null terminated protocol name. If
            this pointer is NULL, getservbyname() returns the first
            service entry for which the name matches the s_name or one
            of the s_aliases. Otherwise getservbyname() matches both
            the name and the proto.

Returns:

    If no error occurs, getservbyname() returns a pointer to the servent
    structure described above. Otherwise it returns a NULL pointer and a
    specific error code is stored with SetErrorCode().

--*/
{
    PCHAR pszTemp;
    struct servent * sent;
    int err, ErrorCode;
    PDPROCESS Process;
    PDTHREAD Thread;
    LPBLOB pBlob;
    PCHAR pResults;

    err = PROLOG(&Process,
                 &Thread,
                 &ErrorCode);
    if(err != NO_ERROR)
    {
        SetLastError(ErrorCode);
        return(NULL);
    }

    pResults = new CHAR[RNR_BUFFER_SIZE];

    if(!pResults)
    {
        SetLastError(WSA_NOT_ENOUGH_MEMORY);
        return(NULL);
    }

    if(!proto)
    {
        proto = "";
    }
    pszTemp = new CHAR[strlen(name) + strlen(proto) + 1 + 1];
    wsprintfA(pszTemp, "%s/%s", name, proto);
    pBlob = getxyDataEnt(pResults,
                        RNR_BUFFER_SIZE,
                        pszTemp,
                        &IANAGuid,
                        0
                        );
    delete pszTemp;
    if(!pBlob)
    {
        sent = 0;
        if(GetLastError() == WSATYPE_NOT_FOUND)
        {
            SetLastError(WSANO_DATA);
        }
    }
    else
    {
        sent = (struct servent *)Thread->CopyServEnt(pBlob);
        if(sent)
        {
            UnpackServEnt(sent);
        }
    }
    delete pResults;
    return(sent);
}  // getservbyname

//
// Common routine for obtaining a xxxent buffer. Input is used to
// execute the WSALookup series of APIs.
//
// Args:
//   pResults -- a buffer supplied by the caller to be used in
//               the WASLookup calls. This should be as large as
//               the caller can afford to offer.
//   dwLength -- number of bytes in pResults
//   lpszName -- pointer to the service name. May by NULL
//   lpType   -- pointer to the service type . This should be one of
//               the SVCID_INET_xxxxx types. It may be anything
//               that produces a BLOB.
//   lppName  -- pointer to pointer where the resulting name pointer
//               is stored. May be NULL if the name is not needed.
//
// Returns:
//   0  --   No BLOB data was returned. In general, this means the
//           operation failed. Evev if the WSALookupNext succeeded
//           and returned a name, the name will not be returned.
//   else -- a pointer to the BLOB.
//
//
//
// The protocol restrictions list for all emulation operations. This
// should limit the invoked providers to the set that know about
// hostents and servents. If not, then the special SVCID_INET GUIDs
// should take care of the remainder.
//
AFPROTOCOLS afp[2] = {
                      {AF_INET, IPPROTO_UDP},
                      {AF_INET, IPPROTO_TCP}
                     };

LPBLOB
getxyDataEnt(
    PCHAR pResults,
    DWORD dwLength,
    LPSTR lpszName,
    LPGUID lpType,
    LPSTR *  lppName)
{

    PWSAQUERYSETA pwsaq = (PWSAQUERYSETA)pResults;
    int err;
    HANDLE hRnR;
    LPBLOB pvRet = 0;
    INT Err = 0;

    //
    // create the query
    //
    memset(pwsaq, 0, sizeof(*pwsaq));
    pwsaq->dwSize = sizeof(*pwsaq);
    pwsaq->lpszServiceInstanceName = lpszName;
    pwsaq->lpServiceClassId = lpType;
    pwsaq->dwNameSpace = NS_ALL;
    pwsaq->dwNumberOfProtocols = 2;
    pwsaq->lpafpProtocols = &afp[0];

    err = WSALookupServiceBeginA(pwsaq,
                                 LUP_RETURN_BLOB | LUP_RETURN_NAME,
                                 &hRnR);

    if(err == NO_ERROR)
    {
        //
        // The query was accepted, so execute it via the Next call.
        //
        err = WSALookupServiceNextA(
                                hRnR,
                                0,
                                &dwLength,
                                pwsaq);
        //
        // if NO_ERROR was returned and a BLOB is present, this
        // worked, just return the requested information. Otherwise,
        // invent an error or capture the transmitted one.
        //

        if(err == NO_ERROR)
        {
            if(pvRet = pwsaq->lpBlob)
            {
                if(lppName)
                {
                    *lppName = pwsaq->lpszServiceInstanceName;
                }
            }
            else
            {
                err = WSANO_DATA;
            }
        }
        else
        {
            //
            // WSALookupServiceEnd clobbers LastError so save
            // it before closing the handle.
            //

            err = GetLastError();
        }
        WSALookupServiceEnd(hRnR);

        //
        // if an error happened, stash the value in LastError
        //

        if(err != NO_ERROR)
        {
            SetLastError(err);
        }
    }
    return(pvRet);
}


Additional Windows Sockets 2 SPI Concerns


Service Provider Ordering

The order in which transport service providers are initially installed governs the order in which they are enumerated through WSCEnumProtocols at the service provider interface, or through WSAEnumProtocols at the application interface. More importantly, this order also governs the order in which protocols and service providers are considered when a client requests creation of a socket based on its address family, type, and protocol identifier. Windows Sockets 2 includes an applet called SPORDER.EXE that allows the catalog of installed protocols to be re-ordered interactively after protocols have already been installed. Windows Sockets 2 also includes an auxiliary DLL, SPORDER.DLL, that exports a procedural interface for re-ordering protocols. This procedural interface consists of a single procedure called WSCWriteProviderOrder.

The interface definition may be imported into a C or C++ program by means of the include file SPORDER.H. The entry point may be linked by means of the lib file SPORDER.LIB. The actual procedure specification is given in the following section.


Windows Sockets SPI Header File - WS2SPI.H

The function prototypes and structures in this document can be found in WS2SPI.H.

New versions of WS2SPI.H will appear periodically as new identifiers are allocated by the Windows Sockets Identifier Clearinghouse. The clearinghouse can be reached via the world wide web:

http://www.stardust.com/wsresource/winsock2/ws2ident.html

Developers are urged to stay current with successive revisions of WS2SPI.H as they are made available by the clearinghouse.


NSPCleanup

The NSPCleanup function terminates the use of a particular Windows Sockets name space service provider.

int NSPCleanup (
  LPGUID lpProviderId
);

Parameters

lpProviderId
[in] A pointer to the GUID of the name space provider that is to be terminated.

Remarks

The NSPCleanup function is called when an application is finished using a Windows Sockets name space service provider. The NSPCleanup function deregisters a particular name space provider and allows the transport service provider to free any of the the name space provider's allocated resources.

The NSPStartup function must be called successfully before using any name space providers. It is permissible to make more than one NSPStartup call. However, for each NSPStartup call, a corresponding NSPCleanup call must also be issued. Only the final NSPCleanup for the service provider does the actual cleanup; the preceding calls simply decrement an internal reference count in the service provider.

This function should not return until the name space service provider DLL can be unloaded from memory.

Return Values

If no error occurs, NSPCleanup returns a value of NO_ERROR (zero). Otherwise, SOCKET_ERROR (-1) is returned and the provider must set the appropriate error code using SetLastError.

Error Codes

WSAEINVAL | The lpProviderId does not specify a valid provider.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.


NSPGetServiceClassInfo

The NSPGetServiceClassInfo function retrieves all of the pertinent class information (schema) pertaining to the name space provider. This call retrieves any name space-specific information that is common to all instances of the service, including connection information for SAP, or port information for SAP or TCP.

int NSPGetServiceClassInfo (
  IN    LPGUID lpProviderId,
  IN OUT    LPDWORD lpdwBufSize,
  IN OUT    LPWSASERVICECLASSINFOW lpServiceClassInfo
);

Parameters

lpProviderId
A pointer to the GUID of the specific name space provider from which the service class schema is to be retrieved.
lpdwBufSize
The number of bytes contained in the buffer pointed to by lpServiceClassInfo on input. Alternately, if the function fails and the error is WSAEFAULT, lpdwBufSize contains the minimum number of bytes to pass for the lpServiceClassInfo to retrieve the record on output.
lpServiceClasslnfo
Returns service class to name space-specific mapping information. The lpServiceClassId field must be filled in to indicate which WSASERVICECLASSINFOW record should be returned.

Remarks

The W2_32.DLL uses this function to implement the WSAGetServiceClassNameByServiceClassId function, as well as to retrieve the name space specific information passed into the NSPLookupServiceBegin and NSPSetService.

Return Values

If no error occurs, the NSPGetServiceClassInfo function returns NO_ERROR (zero). Otherwise, SOCKET_ERROR (-1) is returned and it must set the appropriate error code using SetLastError.

Error Codes

WSAEACCES | The calling routine does not have sufficient privileges to access the information.
WSAEFAULT | The lpServiceClass buffer was too small to contain a WSASERVICECLASSINFOW.
WSAEINVAL | The specified service class ID or name space provider ID is invalid.
WSATYPE_NOT_FOUND | The specified class was not found in any of the name spaces.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


NSPInstallServiceClass

The NSPInstallServiceClass function registers service class schema within the name space providers.

The schema includes the class name, class id, and any name space-specific type information that is common to all instances of the service, such as SAP ID or object ID. A dynamic name space provider is expected to store any class information associated with that namespace. Other name space providers should do whatever makes sense.

int NSPInstallServiceClass (
  LPGUID lpProviderId,
  LPWSASERVICECLASSINFOW lpServiceClassInfo
);

Parameters

lpProviderId
[in] Pointer to the GUID of the specific name space provider that this service class schema is being registered in.
lpServiceClasslnfo
[in] Contains service class schema information.

Remarks

Name space providers are encouraged, but not required to store information that is specific to the name space that they suport.

Return Values

The function should return NO_ERROR (zero) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError.

Error Codes

WSAEACCES | The calling routine does not have sufficient privileges to perform this operation.
WSAEALREADY | Service class information has already been registered for this service class ID. To modify service class info, first use NSPRemoveServiceClass, then re-install with updated class info data.
WSAEINVAL | The service class ID was invalid or improperly structured.
WSA_INVALID_PARAMETER | The name space provider cannot supply the requested class information.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


NSPLookupServiceBegin

The WSALookupServiceBegin function initiates a client query that is constrained by the information contained within a WSAQUERYSET structure.

WSALookupServiceBegin only returns a handle, which should be used by subsequent calls to WSALookupServiceNext to get the actual results. Since this operation can not be canceled, it should be implemented to execute quickly. While it is acceptable to initiate a network query, this function should not require a response in order to return successfully.

int NSPLookupServiceBegin (
  LPGUID lpProviderId,
  LPWSAQUERYSETW lpqsRestrictions,
  LPWSASERVICECLASSINFOW lpServiceClassInfo,
  DWORD dwControlFlags,
  LPHANDLE lphLookup
);

Parameters

lpProviderId
[in] Contains the specific provider ID that should be used for the query.
lpqsRestrictions
[in] Contains the search criteria. See below for more information.
lpServiceClassInfo
[in] A WSASERVICECLASSINFOW structure which contains all of the schema information for the service.
dwControlFlags
[in] Controls the depth of the search:
LUP_DEEP | Query deep as opposed to just the first level.
LUP_CONTAINERS | Return containers only
LUP_NOCONTAINERS | Do not return any containers
LUP_FLUSHCACHE | If the provider has been caching information, ignore the cache and go query the name space itself.
LUP_FLUSHPREVIOUS | Used as a value for the dwControlFlags argument in NSPLookupServiceNext. Setting this flag instructs the provider to discard the last result set, which was too large for the supplied buffer, and move on to the next result set.
LUP_NEAREST | If possible, return results in the order of distance. The measure of distance is provider specific.
LUP_RES_RESERVICE | This indicates whether prime response is in the remote or local part of CSADDR_INFO structure. The other part needs to ber"usable" in either case.
LUP_RETURN_ALIASES | Any available alias information is to be returned in successive calls to NSPLookupServiceNext, and each alias returned will have the RESULT_IS_ALIAS flag set.
LUP_RETURN_NAME | Retrieve the name as lpszServiceInstanceName.
LUP_RETURN_TYPE | Retrieve the type as lpServiceClassId.
LUP_RETURN_WSAVERSION | Retrieve the version as lpVersion.
LUP_RETURN_COMMENT | Retrieve the comment as lpszComment.
LUP_RETURN_ADDR | Retrieve the addresses as lpcsaBuffer.
LUP_RETURN_BLOB | Retrieve the private data as lpBlob.
LUP_RETURN_ALL | Retrieve all of the information.

lphLookup
[out] Handle to be used in subsequent calls to NSPLookupServiceNext in order to retrieve the results set.

Remarks

If LUP_CONTAINERS is specified in a call, all other restriction values should be avoided. If any are supplied, it is up to the name service provider to decide if it can support this restriction over the containers. If it cannot, it should return an error.

Some name service providers may have other means of finding containers. For example, containers can all be of some well-known type, or of a set of well-known types, and therefore a query restriction could be created for finding them. No matter what other means the name service provider has for locating containers, LUP_CONTAINERS and LUP_NOCONTAINERS take precedence. Hence, if a query restriction is given that includes containers, specifying LUP_NOCONTAINERS will prevent the container items from being returned. Similarly, no matter the query restriction, if LUP_CONTAINERS is given, only containers should be returned. If a name space does not support containers, and LUP_CONTAINERS is specified, it should simply return WSANO_DATA.

The preferred method of obtaining the containers within another container, is the call:

dwStatus = NSPLookupServiceBegin(
    lpqsRestrictions,
    LUP_CONTAINERS,
    lphLookup);

followed by the requisite number of NSPLookupServiceNext calls. This will return all containers contained immediately within the starting context; that is, it is not a deep query. With this, one can map the address space structure by walking the hierarchy, perhaps enumerating the content of selected containers. Subsequent uses of NSPLookupServiceBegin use the containers returned from a previous call.

Forming Queries

As mentioned above, a WSAQUERYSET structure is used as an input parameter to NSPLookupServiceBegin in order to qualify the query. The following table indicates how the WSAQUERYSET is used to construct a query. When a field is marked as (Optional) a NULL pointer can be supplied, indicating that the field will not be used as a search criteria. See section Query-Related Data Structures for additional information.

WSAQUERYSET Field Name | Query Interpretation
dwSize | Will be set to sizeof(WSAQUERYSET). This is a versioning mechanism.
dwOuputFlags | Ignored for queries.
lpszServiceInstanceName | (Optional) Referenced string contains service name. The semantics for wildcarding within the string are not defined, but can be supported by certain name space providers.
lpServiceClassId | (Required) The GUID corresponding to the service class.
lpVersion | (Optional) References desired version number and provides version comparison semantics (that is, version must match exactly, or version must be not less than the value supplied).
lpszComment | Ignored for queries.
dwNameSpace | Identifier of a single name space in which to constrain the search, or NS_ALL to include all name spaces.
lpNSProviderId | (Optional) References the GUID of a specific name space provider, and limits the query to this provider only.
lpszContext | (Optional) Specifies the starting point of the query in a hierarchical name space.
dwNumberOfProtocols | Size of the protocol constraint array, can be zero.
lpafpProtocols | (Optional) References an array of AFPROTOCOLS structure. Only services that utilize these protocols will be returned. It is legal for the value AF_UNSPEC to appear as a protocol family value, signifying a wild card. Name space providers may supply information on any service that uses the corresponding protocol, regardless of address family.
lpszQueryString | (Optional) Some namespaces (such as whois++) support enriched SQL like queries which are contained in a simple text string. This parameter is used to specify that string.
dwNumberOfCsAddrs | Ignored for queries.
lpcsaBuffer | Ignored for queries.
lpBlob | (Optional) This is a pointer to a provider-specific entity.

Return Values

The function should return NO_ERROR (zero) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError.

Error Codes

WSAEINVAL | One or more parameters were invalid for this provider or missing.
WSANO_DATA | The name was found in the database but it does not have the correct associated data being resolved for.
WSASERVICE_NOT_FOUND | No such service is known. The service cannot be found in the specified name space.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


NSPLookupServiceEnd

The NSPLookupServiceEnd function is called to free the handle after previous calls to NSPLookupServiceBegin and NSPLookupServiceNext.

It is possible to receive a NSPLookupServiceEnd call on another thread while processing a NSPLookupServiceNext. This indicates that the client has canceled the request, and the provider should close the handle and return from the NSPLookupServiceNext call as well, setting the last error to WSA_E_CANCELLED.

int NSPLookupServiceEnd (
  HANDLE hLookup
);

Parameters

hLookup
[in] Handle previously obtained by calling NSPLookupServiceBegin.

Remarks

In Windows Sockets 2, conflicting error codes are defined for WSAECANCELLED (10103) and WSA_E_CANCELLED (10111). The error code WSAECANCELLED will be removed in a future version and only WSA_E_CANCELLED will remain. Name Space Providers should switch to using the WSA_E_CANCELLED error code as soon as possible to maintain compatibility with the widest possible range of applications.

Return Values

The function should return NO_ERROR (zero) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError.

Error Codes

WSA_INVALID_HANDLE | The handle is not valid.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


NSPLookupServiceNext

The NSPLookupServiceNext function is called after obtaining a Handle from a previous call to NSPLookupServiceBegin in order to retrieve the requested service information.

The provider will pass back a WSAQUERYSET structure in the lpqsResults buffer. The client should continue to call this function until it returns WSA_E_NOMORE, indicating that all of the WSAQUERYSET have been returned.

int NSPAPI WSALookupServiceNext (
  HANDLE hLookup,
  DWORD dwControlFlags,
  LPDWORD lpdwBufferLength,
  LPWSAQUERYSET lpqsResults
);

Parameters

hLookup
[in] Handle returned from the previous call to WSALookupServiceBegin.
dwControlFlags
[in] Flags to control the next operation. Currently only LUP_FLUSHPREVIOUS is defined as a means to cope with a result set that is too large. If an application does not wish to (or cannot) supply a large enough buffer, setting LUP_FLUSHPREVIOUS instructs the provider to discard the last result set—which was too large—and move to the next set for this call.
lpdwBufferLength
[in/out] on input, the number of bytes contained in the buffer pointed to by lpqsResults. On output, if the function fails, and the error is WSAEFAULT, then it contains the minimum number of bytes to pass for the lpqsResults to retrieve the record.
lpqsResults
[out] a pointer to a block of memory, which will contain one result set in a WSAQUERYSET structure on return.

Remarks

The dwControlFlags specified in this function and the ones specified at the time of NSPLookupServiceBegin are treated as "restrictions" for the purpose of combination. The restrictions are combined between the ones at NSPLookupServiceBegin timeand the ones at NSPLookupServiceNext time.Therefore the flags at NSPLookupServiceNext can never increase the amount of data returned beyond what was requested at NSPLookupServiceBegin, although it is NOT an error to specify more or fewer flags.The flags specified at a given NSPLookupServiceNext apply only to that call.

The dwControlFlags LUP_FLUSHPREVIOUS and LUP_RES_SERVICE are exceptions to the "combined restrictions" rule (because they are "behavior" flags instead of "restriction" flags).If either of these flags are used in NSPLookupServiceNext they have their defined effect regardless of the setting of the same flags at NSPLookupServiceBegin.

For example, if LUP_RETURN_VERSION is specified at NSPLookupServiceBegin the service provider retrieves records including the "version".If LUP_RETURN_VERSION is NOT specified at NSPLookupServiceNext, the returned information does not include the "version", even though it was available.No error is generated.

Also for example, if LUP_RETURN_BLOB is NOT specified at NSPLookupServiceBegin but is specified at NSPLookupServiceNext, the returned information does not include the private data.No error is generated.

Query Results

The following table describes how the query results are represented in the WSAQUERYSET structure. Refer to section Query-Related Data Structures for additional information.

WSAQUERYSET Field Name | Result Interpretation
dwSize | Will be set to sizeof(WSAQUERYSET). This is used as a versioning mechanism.
dwOuputFlags | The RESULT_IS_ALIAS flag indicates this is an alias result.
lpszServiceInstanceName | Referenced string contains service name.
lpServiceClassId | The GUID corresponding to the service class.
lpVersion | References version number of the particular service instance.
lpszComment | Optional comment string supplied by service instance.
dwNameSpace | Name space in which the service instance was found.
lpNSProviderId | Identifies the specific name space provider that supplied this query result.
lpszContext | Specifies the context point in a hierarchical name space at which the service is located.
dwNumberOfProtocols | Undefined for results.
lpafpProtocols | Undefined for results, all needed protocol information is in the CSADDR_INFO structures.
lpszQueryString | When dwControlFlags includes LUP_RETURN_QUERY_STRING, this field returns the unparsed remainder of the lpszServiceInstanceName specified in the original query.For example, in a name space that identifies services by hierarchical names that specify a host name and a file path within that host, the address returned might be the host address and the unparsed remainder might be the file path.If the lpszServiceInstanceName is fully parsed and LUP_RETURN_QUERY_STRING is used, this field is NULL or points to a zero-length string.
dwNumberOfCsAddrs | Indicates the number of elements in the array of CSADDR_INFO structures.
lpcsaBuffer | A pointer to an array of CSADDR_INFO structures, with one complete transport address contained within each element.
lpBlob | (Optional) This is a pointer to a provider-specific entity.

Return Values

The function should return NO_ERROR (zero) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError.

Error Codes

WSA_E_NO_MORE | There is no more data available. In Windows Sockets 2, conflicting error codes are defined for WSAENOMORE (10102) and WSA_E_NO_MORE (10110).The error code WSAENOMORE will be removed in a future version and only WSA_E_NO_MORE will remain.Name Space Providers should switch to using the WSA_E_NO_MORE error code as soon as possible to maintain compatibility with the widest possible range of applications.
WSA_E_CANCELLED | A call to NSPLookupServiceEnd was made while this call was still processing. The call has been canceled. The data in the lpqsResults buffer is undefined. In Windows Sockets 2, conflicting error codes are defined for WSAECANCELLED (10103) and WSA_E_CANCELLED (10111).The error code WSAECANCELLED will be removed in a future version and only WSA_E_CANCELLED will remain.Name Space Providers should switch to using the WSA_E_CANCELLED error code as soon as possible to maintain compatibility with the widest possible range of applications.
WSAEFAULT | The lpqsResults buffer was too small to contain a WSAQUERYSET set.
WSAEINVAL | One or more parameters were invalid or missing for this provider.
WSA_INVALID_HANDLE | The specified lookup handle is invalid.
WSANO_DATA | The name was found in the database but no data matching the given restrictions was located
WSASERVICE_NOT_FOUND | No such service is known. The service cannot be found in the specified name space.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


NSPRemoveServiceClass

The NSPRemoveServiceClass function permanently removes a specified service class from the name space.

int NSPRemoveServiceClass (
  IN    LPGUID lpProviderId,
  IN    LPGUID lpServiceClassId
);

Parameters

lpProviderId
[in] Pointer to the GUID of the specific name space provider that this service class schema is to be removed from.
lpServiceClassId
[in] Pointer to the GUID for the service class to remove.

Return Values

The function should return NO_ERROR (zero) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError.

Error Codes

WSATYPE_NOT_FOUND | The specified class was not found in any of the name spaces.
WSAEACCES | The calling routine does not have sufficient privileges to remove the Service.
WSA_INVALID_PARAMETER | The specified GUID was not valid.
WSAEINVAL | The specified service class Id GUID was not valid.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


NSPSetService

The NSPSetService function registers or deregisters a service instance within a name space.

int NSPSetService (
  LPGUID lpProviderId,
  LPWSASERVICECLASSINFOW lpServiceClassInfo,
  LPWSAQUERYSETW lpqsRegInfo,
  WSAESETSERVICEOP essOperation,
  DWORD dwControlFlags
);

Parameters

lpProviderId
[in] Pointer to the GUID of the specific name space provider that this service is being registered in.
lpServiceClasslnfo
[in] Contains service class schema information.
lpqsRegInfo
[in] Specifies property information to be updated upon registration.
essOperation
[in] an enumeration whose values include:
RNRSERVICE_REGISTER
Register the service. For SAP, this means sending out a periodic broadcast. This is a NOP for the DNS name space. For persistent data stores this means updating the address information.
RNRSERVICE_DEREGISTER
Deregister the service. For SAP, this means stop sending out the periodic broadcast. This is a NOP for the DNS name space. For persistent data stores this means deleting address information.
RNRSERVICE_DELETE
Delete the service from dynamic name and persistent spaces. For services represented by multiple CSADDR_INFO structures (using the SERVICE_MULTIPLE flag), only the supplied address will be deleted, and this must match exactly the corresponding CSADD_INFO structure that was supplied when the service was registered.
dwControlFlags
[in] A set of control flags whose values include:
SERVICE_MULTIPLE
Controls scope of operation. When clear, service addresses are managed as a group. A register or deregister invalidates all existing addresses before adding the given address set. When set, the action is only performed on the given address set. A register does not invalidate existing addresses and a deregister only invalidates the given set of addresses.

The available values for essOperation and dwControlFlags combine to give meanings as shown in the following table:

Operation | Flags | Service already exists | Service does not exist
RNRSERVICE _REGISTER | none | Overwrite the object. Use only addresses specified. Object is REGISTERED. | Create a new object. Use only addresses specified. Object is REGISTERED.
RNRSERVICE _REGISTER | SERVICE _MULTIPLE | Update object. Add new addresses to existing set. Object is REGISTERED. | Create a new object. Use all addresses specified. Object is REGISTERED.
RNRSERVICE _DEREGISTER | none | Remove all addresses, but do not remove object from name space. Object is DEREGISTERED. | WSASERVICE _NOT_FOUND
RNRSERVICE _DEREGISTER | SERVICE _MULTIPLE | Update object. Remove only addresses that are specified. Only mark object as DEREGISTERED if no addresses present. Do not remove from the name space. | WSASERVICE _NOT_FOUND
RNRSERVICE _DELETE | none | Remove object from the name space. | WSASERVICE _NOT_FOUND
RNRSERVICE _DELETE | SERVICE _MULTIPLE | Remove only addresses that are specified. Only remove object from the name space if no addresses remain. | WSASERVICE _NOT_FOUND

Remarks

SERVICE_MULTIPLE lets an application manage its addresses independently. This is useful when the application wants to manage its protocols individually or when the service resides on more than one machine. For instance, when a service uses more than one protocol, it may find that one listening socket aborts but the others remain operational. In this case, the service could deregister the aborted address without affecting the other addresses.

When using SERVICE_MULTIPLE, an application must not let stale addresses remain in the object. This can happen if the application aborts without issuing a DEREGISTER request. When a service registers, it should store its addresses. On its next invocation, the service should explicitly deregister these old stale addresses before registering new addresses.

Service Properties

The following table describes how service property data is represented in a WSAQUERYSET structure. Fields labeled as (Optional) can be supplied with a NULL pointer.

WSAQUERYSET Field Name | Service Property Description
dwSize | Must be set to sizeof(WSAQUERYSET). This is a versioning mechanism.
dwOuputFlags | Not applicable and ignored.
lpszServiceInstanceName | Referenced string contains the service instance name.
lpServiceClassId | The GUID corresponding to this service class.
lpVersion | (Optional) Supplies service instance version number.
lpszComment | (Optional) An optional comment string.
dwNameSpace | Ignored for this operation.
lpNSProviderId | Ignored for this operation, provider ID is contained in the lpProviderId parameter.
lpszContext | (Optional) Specifies the starting point of the query in a hierarchical name space.
dwNumberOfProtocols | Ignored.
lpafpProtocols | Ignored.
lpszQueryString | Ignored.
dwNumberOfCsAddrs | The number of elements in the array of CSADDRO_INFO structures referenced by lpcsaBuffer.
lpcsaBuffer | A pointer to an array of CSADDRO_INFO structures which contain the address[es] that the service is listening on.
lpBlob | (Optional) This is a pointer to a provider-specific entity.

Note It is legal for the iProtocol field of the CSADDR_INFO structure to contain the manifest constant IPROTOCOL_ANY, signifying a wildcard value. The name space provider should substitute a value that is reasonable for the given the address family and socket type.

Return Values

The function should return NO_ERROR (zero) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError.

Error Codes

WSAEACCES | The calling routine does not have sufficient privileges to install the service.
WSAEINVAL | One or more parameters were invalid or missing for this provider.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.
WSASERVICE_NOT_FOUND | No such service is known. The service cannot be found in the specified name space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


NSPStartup

The NSPStartup function retrieves the dynamic information about a provider, such as the list of the DLL entry points.

This function is called by the client upon initialization. NSPStartup and NSPCleanup must be called as pairs. All of the NSP functions must be called from within a NSPStartup/NSPCleanup pair. WSC functions do not need to be called from within a NSPStartup/NSPCleanup pair either.

int NSPStartup (
  LPGUID lpProviderId,
  LPNSP_ROUTINE lpnspRoutines
);

Parameters

lpProviderId
[in] Indicates the desired provider for which to return the entry points.
lpnspRoutines
[out] Pointer to all of the Provider entry points.

Data Types

The following data types are needed for this call.

NSP_ROUTINE
The NSP_ROUTINE structure contains information regarding all of the functions implemented by a given provider.
typedef struct _NSP_ROUTINE {
    DWORD        cbSize;
    DWORD        dwMajorVersion;
    DWORD        dwMinorVersion;
    INT ( *NSPCleanup) ;
    INT ( *NSPLookupServiceBegin) ;
    INT ( *NSPLookupServiceNext) ;
    INT ( *NSPLookupServiceEnd) ;
    INT ( *NSPSetService) ;
    INT ( *NSPInstallServiceClass) ;
    INT ( *NSPRemoveServiceClass) ;
    INT ( *NSPGetServiceClassInfo) ;
} NSP_ROUTINE, *PNSP_ROUTINE, *LPNSP_ROUTINE;
cbSize
Size of this structure.
dwMajorVersion
The major version of the service provider specification supported by this provider.
dwMinorVersion
The minor version of the service provider specification supported by this provider.
*NSP*.*
Pointers to the various NSP functions. Every entry must point to a valid function. If the provider does not implement this function, it should simply return WSAENOTIMPLEMENTED.

Note In the header file this structure contains complete prototypes for all of the NSP pointers.

Return Values

The function should return NO_ERROR (zero) if the routine succeeds. It should return SOCKET_ERROR (-1) if the routine fails and it must set the appropriate error code using SetLastError.

WSAEINVAL | One or more parameters were invalid or missing for this provider.
WSA_NOT_ENOUGH_MEMORY | Not enough free memory available to perform this operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


WPUCloseEvent

The WPUCloseEvent function closes an open event object handle.

BOOL WPUCloseEvent (
  WSAEVENT hEvent,
  LPINT lpErrno
);

Parameters

hEvent
[in] A handle to an open event object.
lpErrno
[out] A pointer to the error code.

Return Values

If the function succeeds, the return value is TRUE.

Otherwise, the return value is FALSE and a specific error code is available in lpErrno.

Error Codes

WSA_INVALID_HANDLE hEvent is not a valid event object handle.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCreateEvent


WPUCloseSocketHandle

The WPUCloseSocketHandle function closes an existing socket handle.

int WPUCloseSocketHandle (
  SOCKET s,
  LPINT lpErrno
);

Parameters

s
[in] A handle to socket created with WPUCreateSocketHandle.
lpErrno
[out] A pointer to the error code.

Remarks

Th WPUCloseSocketHandle function closes an existing socket handle created by WPUCreateSocketHandle. This function removes the socket from WS2_32.DLL's internal socket table. The owning service provider is responsible for releasing any resources associated with the socket.

Return Values

If no error occurs, WPUCreateSocketHandle returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAENOTSOCK The descriptor is not a socket created by WPUCreateSocketHandle.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCreateSocketHandle


WPUCloseThread

The WPUCloseThread function closes a thread opened with a call to WPUOpenCurrentThread.

INT WSPAPI WPUCloseThread (
  LPWSATHREADID lpThreadId,
  LPINT lpErrno
);

Parameters

lpThreadId
[in] A pointer to a WSATHREADID structure that identifies the thread context. This structure must have been initialized by a previous call to WPUOpenCurrentThread.
lpErrno
[out] A pointer to the error code.

Remarks

The WPUCloseThread function is used in a layered service provider to deallocate the resources that were initiated in a call by the WPUOpenCurrentThread function. The WSATHREADID structure in the lpThreadId is the thread to deallocate.

Every call to WPUOpenCurrentThread must have a call to WPUCloseThread. These two functions are used when the overlapped functions, such as WSPSend, are called in a lower layer of the service provider than the current thread.

Return Values

If no error occurs, WPUOpenCurrentThread returns the zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSANOTINITIALISED A successful WSPStartup must occur before using this function.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCloseThread, WPUOpenCurrentThread


WPUCompleteOverlappedRequest

The WPUCompleteOverlappedRequest function performs overlapped I/O completion notification for overlapped I/O operations.

WSAEVENT WPUCompleteOverlappedRequest (
  SOCKET s,
  LPWSAOVERLAPPED lpOverlapped,
  DWORD dwError,
  DWORD cbTransferred,
  LPINT lpErrno
);

Parameters

s
[in] Service provider socket created by WPUCreateSocketHandle.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure associated with the overlapped I/O operation whose completion is to be notified.
dwError
[in] Completion status of the overlapped I/O operation whose completion is to be notified.
cbTransferred
[in] Number of bytes transferred to or from client buffers (the direction of the transfer depends on the send or receive nature of the overlapped I/O operation whose completion is to be notified).
lpErrno
[out] A pointer to the error code resulting from execution of this function.

Remarks

The WPUCompleteOverlappedRequest function performs overlapped I/O completion notification for overlapped I/O operations where the client-specified completion mechanism is something other than user mode Asynchronous Procedure Call (APC). This function can only be used for socket handles created by WPUCreateSocketHandle.

Note This function is different from other functions with the "WPU" prefix in that it is not accessed through the upcall table. Instead, it is exported directly by WS2_32.DLL. Service providers that need to call this function should link with WS2_32.LIB or use appropriate Operating System functions such as LoadLibrary() and GetProcAddress() to retrieve the function pointer.

The function WPUCompleteOverlappedRequest is used by service provider that do not implement Installable File System (IFS) functionality directly for the socket handles they expose. It performs completion notification for any overlapped I/O request for which the specified completion notification is other than a user-mode APC. WPUCompleteOverlappedRequest is supported only for the socket handles created by WPUCreateSocketHandle and not for sockets created by a service provider directly.

If the client selects a user-mode APC as the notification method, the service provider should use WPUQueueApc or an other appropriate operating system function to perform the completion notification. If user-mode APC is not selected by the client, a service provider that does not implement IFS functionality directly cannot determine whether or not the client has associated a completion port with the socket handle. Thus it cannot determine whether the completion notification method should be queuing a completion status record to a completion port or signaling an event found in the WSAOVERLAPPED structure. The Windows Socket 2 architecture keeps track of any completion port association with a socket created by WPUCreateSocketHandle and can make a correct decision between completion port based notification or event based notification.

When WPUCompleteOverlappedRequest queues a completion indication, it sets the InternalHigh member of the WSAOVERLAPPED structure to the count of bytes transferred. Then it sets the Internal member to some OS-dependent value other than the special value WSS_OPERATION_IN_PROGRESS. There may be some slight delay after WPUCompleteOverlappedRequest returns before these values appear, since processing may occur asynchronously. However, the InternalHigh value (byte count) is guaranteed to be set by the time Internal is set.

WPUCompleteOverlappedRequest is available both on Windows 95 and Windows NT. It works as stated (performs the completion notification as requested by the client) whether or not the socket handle has been associated with a completion port.

Interaction with WSPGetOverlappedResult

The behavior of WPUCompleteOverlappedRequest places some constraints on how a service provider implements WSPGetOverlappedResult since only the Offset and OffsetHigh members of the WSAOVERLAPPED structure are exclusively controlled by the service provider, yet three values (byte count, flags, and error) must be retrieved from the structure by WSPGetOverlappedResult. A service provider may accomplish this any way it chooses as long as it interacts with the behavior of WPUCompleteOverlappedRequest properly. However, a typical implementation is as follows:

  • At the start of overlapped processing, the service provider sets Internal to WSS_OPERATION_IN_PROGRESS.
  • When the IO operation has been completed, the provider sets OffsetHigh to the Widows Socket 2 error code resulting from the operation, sets Offset to the flags resulting from the IO operation, and calls WPUCompleteOverlappedRequest(), passing the transfer byte count as one of the parameters. WPUCompleteOverlappedRequest eventually sets InternalHigh to the transfer byte count, then sets Internal to a value other than WSS_OPERATION_IN_PROGRESS.
  • When WSPGetOverlappedResult is called, the service provider checks Internal. If it is WSS_OPERATION_IN_PROGRESS, the provider waits on the event handle in the hEvent member or returns an error, based on the setting of the fWait flag of WSPGetOverlappedResult. If not in progress, or after completion of waiting, the provider returns the values from InternalHigh, OffsetHigh, and Offset as the transfer count, operation result error code, and flags respectively.

Return Values

If no error occurs, WPUCompleteOverlappedRequest returns 0 and notifies completion of the overlapped I/O operation according to the mechanism selected by the client (signals an event found in the WSAOVERLAPPED structure referenced by lpOverlapped and/or queues a completion status report to the completion port associated with the socket if a completion port is associated). Otherwise, WPUCompleteOverlappedRequest returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAEINVAL The socket s is not a socket created by WPUCreateSocketHandle.

See Also

WSPGetOverlappedResult, WPUCreateSocketHandle, WPUQueueApc


WPUCreateEvent

The WPUCreateEvent function creates a new event object.

WSAEVENT WPUCreateEvent (
  LPINT lpErrno
);

Parameters

lpErrno
[out] A pointer to the error code.

Remarks

The event object created by this function is manual reset with an initial state of nonsignaled. If a Win32 service provider wants auto reset events, it can call the Win32 CreateEvent function directly. For more information, see CreateEvent.

Return Values

If no error occurs, WPUCreateEvent function returns the handle of the event object.

Otherwise, the return value is WSA_INVALID_EVENT and a specific error code is available in lpErrno.

Error Codes

WSA_NOT_ENOUGH_MEMORY Not enough free memory available to create the event object.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCloseEvent


WPUCreateSocketHandle

The WPUCreateSocketHandle function creates a new socket handle.

SOCKET WPUCreateSocketHandle (
  DWORD dwCatalogEntryId,
  DWORD dwContext,
  LPINT lpErrno
);

Parameters

dwCatalogEntryId
[in] A descriptor identifying the calling service provider.
dwContext
[in] A context value to associate with the new socket handle.
lpErrno
[out] A pointer to the error code.

Remarks

The WPUCreateSocketHandle function creates a new socket handle for the specified provider. The handles created by WPUCreateSocketHandle are indistinguishable from true file system handles. This is significant in two respects. First, the Windows Socket 2 architecture takes care of redirecting the file system functions ReadFile and WriteFile to this service provider's WSPRecv and WSPSend functions, respectively. Second, in operating systems that support completion ports, the Windows Sockets 2 architecture supports associating a completion port with the socket handle and using it to report overlapped IO completion.

Note, however, that the mechanism for redirecting ReadFile and WriteFile necessarily involves a user-to-kernel transition to get to the redirector, followed by a kernel-to-user transition to get to WSPRecv or WSPSend. On return, these transitions are retraced in reverse. This can be a significant performance penalty. Any service provider that uses WPUCreateSocketHandle to create its socket handles should not set XP1_IFS_HANDLES in its WSAPROTOCOL_INFOW structure. Clients should take the absence of XP1_IFS_HANDLES as guidance to avoid the use of ReadFile and WriteFile.

There is no exceptional performance penalty for using the completion port mechanism with socket handles created with WPUCreateSocketHandle. A service provider should use WPUCompleteOverlappedRequest to announce completion of overlapped IO operations that may involve a completion port. Clients may freely use operating system functions to create, associate, and use a completion port for completion notification (for example, CreateIoCompletionPort, GetQueuedCompletionStatus, see relevant OS documentation for details). Note that completion ports are not integrated with the other asynchronous notification mechanisms offered by Windows Sockets 2. That is, a client can do a multiple-wait that includes multiple events and completion callbacks, but there is no predefined way for the multiple-wait to include completion ports.

Layered Service Provider considerations

This procedure is of particular interest to Layered Service Providers. A layered service provider may use this procedure, instead of WPUModifyIFSHandle to create the socket handles it exposes to its client. The advantage of using this procedure is that all IO requests involving the socket can be guaranteed to go through this service provider. This is true even if the client assumes that the sockets are file system handles and calls the file system functions ReadFile and WriteFile (although it would pay a performance penalty for this assumption).

The guarantee that all IO goes through this layer is a requirement for layers that need to process the IO stream either before or after the actual IO operation. Creating socket handles using WPUCreateSocketHandle and specifying an appropriate service provider interface procedure dispatch table at the time of WSPStartup makes sure that the layer has the chance to get involved in starting each IO operation. When the client requests overlapped IO operations this service provider layer will usually have to arrange to get into the path of IO completion notification as well.

To see why this is true, consider what happens if the client associates a completion port with the socket handle for the purpose of overlapped IO completion notification. The port is associated with the socket handle exposed by this layer, not the next layer's socket handle. There is no way for this layer to determine if a completion port has been associated or what the port is. When this layer calls the next layer's IO operation, it uses the next layer's socket handle. The next layer's socket handle will not have the same completion port association. The client's expected completion-port notification will not happen without some extra help.

The usual way a layered service provider takes care of this is to substitute a different overlapped IO structure and different overlapped IO parameters when invoking an IO operation in the next layer. The substitute overlapped IO structure references the client's stored overlapped structure and parameters. The invocation of the next layer sets up a callback notification. When the callback notification occurs, this layer performs any post-processing desired, retrieves the overlapped IO information it stored on behalf of the client, discards the substitute structures, and forwards an appropriate completion notification to the client.

Return Values

If no error occurs, WPUCreateSocketHandle returns the new socket handle. Otherwise, it returns INVALID_SOCKET, and a specific error code is available in lpErrno.

Error Codes

WSAENOBUFS Not enough buffers available, too many sockets.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCloseSocketHandle, WPUQuerySocketHandleContext, WPUModifyIFSHandle, WPUCompleteOverlappedRequest


WPUFDIsSet

The WPUFDIsSet function checks the membership of the specified socket handle.

int WPUFDIsSet (
  SOCKET s,
  FD_SET FAR * set
);

Parameters

s
[in] A descriptor identifying the socket.
set
[in] The set to check for the membership of socket s.

Return Values

If no error occurs, a value of nonzero is returned denoting that socket s is a member of the set. Otherwise, the return value is zero.

See Also

WSPSelect


WPUGetProviderPath

The WPUGetProviderPath function retrieves the DLL path for the specified provider.

int WPUGetProviderPath (
  LPGUID lpProviderId,
  LPWSTR lpszProviderDllPath,
  LPINT lpProviderDllPathLen,
  LPINT lpErrno
);

Parameters

lpProviderId
[in] The locally unique identifier of the provider. This must be a value obtained by using WSCEnumProtocols.
lpszProviderDllPath
[out] A pointer to a buffer containing a string that identfies the provider DLL's path. This path is a null-terminated string, and any embedded environment strings (such as %SystemRoot%) have not been expanded.
lpProviderDllPathLen
[in/out] The size of the buffer pointed to by lpszProviderDllPath.
lpErrno
[out] A pointer to the error code.

Remarks

The WPUGetProviderPath function retrieves the DLL path for the specified provider. The DLL path is null-terminated and can contain embedded environment strings (such as %SystemRoot%). Thus, the string should be expanded prior to being used with LoadLibrary. For more information, see LoadLibrary.

Return Values

If no error occurs, WPUGetProviderPath returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAEINVAL | lpProviderId does not specify a valid provider.
WSAEFAULT | lpszProviderDllPath or lpErrno is not in a valid part of the user address space, or lpProviderDllPathLen is too small.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSCInstallProvider, WSCEnumProtocols


WPUModifyIFSHandle

The WPUModityIFSHandle function receives (possibly) modified IFS handle from WS2_32.DLL.

SOCKET WPUModifyIFSHandle (
  DWORD dwCatalogEntryId,
  SOCKET ProposedHandle,
  LPINT lpErrno
);

Parameters

dwCatalogEntryId
[in] A descriptor identifying the calling service provider.
ProposedHandle
[in] An Installable File System(IFS) handle allocated by the provider.
lpErrno
[out] A pointer to the error code.

Remarks

The WPUModityIFSHandle handle allows the WS2_32.DLL to streamline its internal operations by returning a possibly modified version of the supplied IFS handle. It is guaranteed that the returned handle is indistinguishable from the proposed handle as far as the operating system is concerned. IFS providers must call this function before returning any newly created socket descriptor to a service provider. The service provider will only use the modified handle for any subsequent socket operations.

This routine is only used by IFS providers whose socket descriptors are real Installable File System handles.

Layered Service Provider Considerations

This procedure may also be used by a layered provider that is layered on top of a base IFS provider and wants to expose the base provider's socket handles as its own instead of creating them with the WPUCreateSocketHandle call. A layered provider that wishes to "pass through" the IFS socket handles it receives from the next layer in the chain can call WPUModifyIFSHandle, passing its own catalog entry Id as dwCatalogEntryId. This informs the Windows Sockets DLL that this layer, and not the next layer, should be the target for SPI calls involving that socket handle.

There are several limitations a layered provider should observe if it takes this approach.

  • The provider should expose base provider entry points for WSPSend and WSPRecv in the procedure dispatch table it returns at the time of WSPStartup to make sure the Windows Sockets SPI client's access to these functions is as efficient as possible.
  • The provider can not rely on its WSPSend and WSPRecv functions being invoked for all IO, particularly in the case of the IO system functions ReadFile and WriteFile. These functions would bypass the layered provider and invoke the base IFS provider's implementation directly even if the layered provider puts its own entry points for these functions into the procedure dispatch table.
  • The provider can not rely on any ability to post-process overlapped IO using WSPSend, WSPSendTo, WSPRecv, WSPRecvFrom, or WSPIoctl. Post-processing notification may happen through completion ports and bypass the layered provider entirely. A layered provider has no way to determine that a completion port was used or determine what port it is. The layered provider has no way to insert itself into the notification sequence.
  • The provider should pass through all overlapped IO requests directly to the base provider using the original overlapped parameters (for example, WSAOVERLAPPED structure and completion routine pointer). The provider should expose the base provider entry point for WSPGetOverlappedResult. Since some overlapped IO requests can bypass the layered provider completely the layered provider cannot reliably mark WSAOVERLAPPED structures to determine which ones it can report results for, and which ones would have to be passed through to the underlying provider's WSPGetOverlappedResult. This effectively means that WSPIoctl has to be a pass-through operation to the underlying provider.

Return Values

If no error occurs, WPUModifyIFSHandle returns the modified socket handle. Otherwise, it returns INVALID_SOCKET, and a specific error code is available in lpErrno.

Error Codes

WSAEINVAL The proposed handle is invalid.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCreateSocketHandle


WPUOpenCurrentThread

The WPUOpenCurrentThread function opens a handle to the current thread that can be used with overlapped functions in a layered service provider. This is intended to be used by layered service providers that wish to initiate overlapped IO from non-application threads.

INT WPUOpenCurrentThread (
  LPWSATHREADID lpThreadId,
  LPINT lpErrno
);

Parameters

lpThreadId
[out] A pointer to a WSATHREADID structure that can then be passed to an overlapped function.
lpErrno
[out] A pointer to the error code.

Remarks

The WPUOpenCurrentThread function provides a pointer to a WSATHREADID structure that can then be passed to an overlapped function such as WSPSend or WSPRecv. Layered service providers that use a private thread in one of the upper layers will use WPUOpenCurrentThread to pass a WSATHREADID pointer to the lower layer that is administering overlapped functions.

Overlapped functions such as WSPSend and WSPRecv can then be used in the same way as a regular service provider.

Every call to WPUOpenCurrentThread must have a corresponding call to WPUCloseThread.

Return Values

If no error occurs, WPUOpenCurrentThread returns the zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSANOTINITIALISED A successful WSPStartup must occur before using this function.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCloseThread, WSPSend, WSPRecv, WPUOpenCurrentThread


WPUPostMessage

The WPUPostMessage function performs the standard Win32 PostMessage function in a way that maintains backward compatibility with older versions of WSOCK32.DLL.

BOOL WPUPostMessage (
  HWND hWnd,
  UINT Msg,
  WPARAM wParam,
  LPARAM lParam
);

Parameters

hWnd
[in] The handle to the window that will receive the message.
Msg
[in] The message that will be posted.
wParam
[in] The first parameter containing additional message-specific information.
lParam
[in] The second paramter containing additional message-specific information.

Return Values

If no error occurs, WPUPostMessage returns the TRUE value. Otherwise, the FALSE value is returned.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


WPUQueryBlockingCallback

The WPUQueryBlockingCallback function returns a pointer to a callback function the service provider should invoke periodically while servicing blocking operations.

int WPUQueryBlockingCallback (
  DWORD dwCatalogEntryId,
  LPBLOCKINGCALLBACK FAR * lplpfnCallback,
  LPDWORD lpdwContext,
  LPINT lpErrno
);

Parameters

dwCatalogEntryId
[in] A descriptor identifying the calling service provider.
lplpfnCallback
[out] A pointer that receives to the blocking callback function.
lpdwContext
[out] A pointer that receives a context value that the service provider must pass into the blocking callback.
lpErrno
[out] A pointer to the error code.

Remarks

The WPUQueryBlockingCallback function returns a pointer to a callback function in lpfnCallback to be invoked periodically during blocking operations. This function also returns a context value in lpdwContext to be passed into the blocking callback.

Under Win32, this function can return NULL in lpfnCallback, indicating that no user-defined blocking hook is installed. In this case, the service provider should use the native Win32 synchronization objects to implement blocking.

LPBLOCKINGCALLBACK is defined as follows:

typedef BOOL ( CALLBACK FAR * LPBLOCKINGCALLBACK )( DWORD dwContext );

The blocking callback will return TRUE if the service provider is to continue waiting for the blocking operation to complete, FALSE if the blocking operation has been canceled with the WSPCancelBlockingCall.

Any missing components of the address will be default to a reasonable values if possible. For example, a missing port number will default to zero.

Return Values

If no error occurs, WPUQueryBlockingCallback returns zero and stores a pointer to a blocking callback function in lpfnCallback and an associated context value in lpdwContext. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAEFAULT | The lpfnCallback or the lpdwContext argument is not a valid part of the process address space.
WSAEINVAL | dwCatalogEntryId is invalid.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPCancelBlockingCall


WPUQuerySocketHandleContext

The WPUQuerySocketHandleContext function queries the context value associated with the specified socket handle.

int WPUQuerySocketHandleContext (
  SOCKET s,
  LPDWORD lpContext,
  LPINT lpErrno
);

Parameters

s
[in] A descripton identifying the socket whose context is to be queried.
lpContext
[out] A pointer that will receive the context value.
lpErrno
[out] A pointer to the error code.

Remarks

The WPUQuerySocketHandleContext function queries the current context value associated with the specified socket handle. Service providers typically use this function to retrieve a pointer to provider-specific data associated with the socket. For example, a service provider can use the socket context to store a pointer to a structure containing the socket's state, local and remote transport addresses, and event objects for signaling network events.

This function is only used by non-IFS providers since IFS providers are not able to supply a context value.

Return Values

If no error occurs, WPUQuerySocketHandleContext returns zero and stores the current context value in lpContext. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAENOTSOCK The descriptor is not a socket created by WPUCreateSocketHandle.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCreateSocketHandle


WPUQueueApc

The WPUQueueApc function queues a user-mode asynchronous procedure call (APC) to the specified thread in order to facilitate invocation of overlapped I/O completion routines.

int WPUQueueApc (
  LPWSATHREADID lpThreadId,
  LPWSAUSERAPC lpfnUserApc,
  DWORD dwContext,
  LPINT lpErrno
);

Parameters

lpThreadId
[in] A pointer to a WSATHREADID structure that identifies the thread context. A pointer to this structure is supplied to the service provider by the WS2_32.DLL as in input parameter to an overlapped operationThe provider should store the WSATHREADID structure locally and provide a pointer to this local store. The local copy of WSATHREADID is no longer needed once WPUQueueApc returns.
lpfnUserApc
[in] Points to the APC function to be called.
dwContext
[in] A 32-bit context value which is subsequently supplied as an input parameter to the APC function.
lpErrno
[out] A pointer to the error code.

Remarks

This function queues an APC function against the specified thread. Under Win32, this will be done using a user mode asynchronous procedure call (APC). The APC will only execute when the specified thread is blocked in an alertable wait. For Win16, a callback will be made directly. In Win16 environments, this call is safe for use within "interrupt context".

LPWSAUSERAPC is defined as follows:

typedef void ( CALLBACK FAR * LPWSAUSERAPC )( DWORD dwContext );

Because the APC mechanism supports only a single 32 bit context value, lpfnUserApc cannot itself be the client-specified completion routine, which involves more parameters. The service provider must instead supply a pointer to its own APC function which uses the supplied dwContext value to access the needed result information for the overlapped operation, and then invokes the client-specified completion routine.

For service providers where a user-mode component implements overlapped I/O a typical usage of the APC mechanism is as follows. When the I/O operation completes, the provider allocates a small buffer and packs it with a pointer to the client-supplied completion procedure and parameter values to pass to the procedure. It queues an APC, specifying the pointer to the buffer as the dwContext value and its own intermediate procedure as the target procedure lpfnUserApc. When the target thread eventually enters alertable wait state, the service provider's intermediate procedure is called in the proper thread context. The intermediate procedure simply unpacks parameters, deallocates the buffer, and calls the client-supplied completion procedure.

Return Values

If no error occurs, WPUQueueApc returns zero and queues the completion routine for the specified thread. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAEFAULT dwThreadId does not specify a valid thread.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPSend, WSPSendTo, WSPRecv, WSPRecvFrom, WSPIoctl


WPUResetEvent

The WPUResetEvent function resets the state of the specified event object to nonsignaled. In Win16 environments, this call is safe for use within "interrupt context".

BOOL WPUResetEvent (
  WSAEVENT hEvent,
  LPINT lpErrno
);

Parameters

hEvent
[in] A handle that identifies an open event object.
lpErrno
[out] A pointer to the error code.

Return Values

If no error occurs, the WPUResetEvent function returns the value TRUE. Otherwise, the FALSE value is returned, and a specific error code is available in lpErrno.

Error Codes

WSA_INVALID_HANDLE hEvent is not a valid event object handle.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCreateEvent, WPUSetEvent, WPUCloseEvent


WPUSetEvent

The WPUSetEvent function sets the state of the specified event object to signaled. In Win16 environments, this call is safe for use within "interrupt context".

BOOL WPUSetEvent (
  WSAEVENT hEvent,
  LPINT lpErrno
);

Parameters

hEvent
[in] A hande that identifies an open event object.
lpErrno
[out] A pointer to the error code.

Return Values

If no error occurs, the WPUSetEvent function returns the value TRUE. Otherwise, the FALSE value is returned, and a specific error code is available in lpErrno.

Error Codes

ERROR_INVALID_HANDLE hEvent is not a valid event object handle.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCreateEvent, WPUResetEvent, WPUCloseEvent


WSCDeinstallProvider

The WSCDeinstallProvider function removes the specified transport provider from the system configuration database.

int WSCDeinstallProvider (
  LPGUID lpProviderId,
  LPINT lpErrno
);

Parameters

lpProviderId
[in] The globally unique identifier of the provider to deinstall. This value is stored within each WSAPROTOCOL_INFOW struct.
lpErrno
[out] A pointer to the error code.

Remarks

The WSCDeinstallProvider function removes the common Windows Sockets 2 configuration information for the specified provider. After this routine completes successfully, the configuration information stored in the registry will be changed. However, any WS2_32.DLL instances that are currently in memory will not be able to see this change.

The caller of this function must remove any additional files or service provider-specific configuration information that is needed to completely de-install the service provider.

Return Values

If no error occurs, WSCDeinstallProvider returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAEINVAL | lpProviderId does not specify a valid provider.
WSAEFAULT | lpErrno is not in a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.
Import Library: Link with ws2_32.lib.

See Also

WSCInstallProvider, WSCEnumProtocols


WSCEnableNSProvider

The WSCEnableNSProvider function changes the state of a given name space provider. It is intended give the end-user the ability to change the state of the name space providers with the control panel applet.

int WSCEnableNSProvider (
  LPGUID lpProviderId,
  BOOL fEnable
);

Parameters

lpProviderId
[in] The locally unique identifier for this provider.
fEnable
[in] A Boolean value that, 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.

Remarks

The name space configuration functions do not affect applications that are already running. Newly installed name space providers will not be visible to applications nor will the changes in a name space provider's activation state. Applications launched after the call to WSCEnableNSProvider will see the changes.

The WSCEnableNSProvider 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 its own. The choice should be left to the user.

Return Values

If no error occurs, the WSCEnableNSProvider function returns NO_ERROR (zero). Otherwise, it returns SOCKET_ERROR and must set the appropriate error code using SetLastError.

Error Codes

WSAEINVAL The specified name space provider ID is invalid.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.
Import Library: Link with ws2_32.lib.


WSCEnumProtocols

The WSCEnumProtocols function retrieves information about available transport protocols.

int WSCEnumProtocols (
  LPINT lpiProtocols,
  LPWSAPROTOCOL_INFOW lpProtocolBuffer,
  LPDWORD lpdwBufferLength,
  LPINT lpErrno
);

Parameters

lpiProtocols
[in] A null-terminated array of iProtocol values. This parameter is optional; if lpiProtocols is NULL, information on all available protocols is returned. Otherwise, information is retrieved only for those protocols listed in the array.
lpProtocolBuffer
[out] A buffer that is filled with WSAPROTOCOL_INFOW structures.
lpdwBufferLength
[in/out] On input, the count of bytes in the lpProtocolBuffer buffer passed to WSCEnumProtocols. On output, the minimum buffer size that can be passed to WSCEnumProtocols to retrieve all the requested information.
lpErrno
[out] A pointer to the error code.

Remarks

This function is used to discover information about the collection of transport protocols installed on the local machine. This function differs from its API counterpart (WSAEnumProtocols) in that WSAPROTOCOL_INFOW structures for all installed protocols, including layered protocols, can be obtained. (WSAEnumProtocols only returns information on base protocols and protocol chains.) The lpiProtocols parameter can be used as a filter to constrain the amount of information provided. Normally, a NULL pointer is supplied so the function will return information on all available transport protocols.

A WSAPROTOCOL_INFOW structure is provided in the buffer pointed to by lpProtocolBuffer for each requested protocol. If the supplied buffer is not large enough (as indicated by the input value of lpdwBufferLength ), the value pointed to by lpdwBufferLength will be updated to indicate the required buffer size. The Windows Sockets SPI client should then obtain a large enough buffer and call this function again. The WSCEnumProtocols function cannot enumerate over multiple calls; the passed-in buffer must be large enough to hold all expected entries in order for the function to succeed. This reduces the complexity of the function and should not pose a problem because the number of protocols loaded on a machine is typically small.

The order in which the WSAPROTOCOL_INFOW structures appear in the buffer coincides with the order in which the protocol entries were registered by the service provider with the WS2_32.DLL, or with any subsequent re-ordering that may have occurred through the Windows Sockets applet supplied for establishing default transport providers.

Return Values

If no error occurs, WSCEnumProtocols returns the number of protocols to be reported on. Otherwise, a value of SOCKET_ERROR is returned and a specific error code is available in lpErrno.

Error Codes

WSAEFAULT | One of more of the arguments is not in a valid part of the user address space.
WSAEINVAL | Indicates that one of the specified parameters was invalid.
WSAENOBUFS | The buffer length was too small to receive all the relevant WSAPROTOCOL_INFOW structures and associated information. Pass in a buffer at least as large as the value returned in lpdwBufferLength.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.
Import Library: Link with ws2_32.lib.


WSCGetProviderPath

The WSCGetProviderPath function retrieves the DLL path for the specified provider.

int WSCGetProviderPath(
  LPGUID lpProviderId,
  LPWSTR lpszProviderDllPath,
  LPINT lpProviderDllPathLen,
  LPINT lpErrno
);

Parameters

lpProviderId
[in] The locally unique identifier of the provider. This value is obtained by using WSCEnumProtocols.
lpszProviderDllPath
[out] A pointer to a buffer into which the provider DLL's path string is returned. The path is a null-terminated string and any embedded environment strings, such as %SystemRoot%, have not been expanded.
lpProviderDllPathLen
[in/out] The size of the buffer pointed to by the lpszProviderDllPath parameter.
lpErrno
[out] A pointer to the error code.

Remarks

The WSCGetProviderPath function retrieves the DLL path for the specified provider. The DLL path can contain embedded environment strings, such as %SystemRoot%, and thus should be expanded prior to being used with the Win32 LoadLibrary function. For more information, see LoadLibrary.

Return Values

If no error occurs, WSCGetProviderPath returns zero. Otherwise, it returns SOCKET_ERROR. The specific error code is available in lpErrno.

Error Codes

WSAEINVAL | The lpProviderId parameter does not specify a valid provider.
WSAEFAULT | The lpszProviderDllPath or lpErrno parameter is not in a valid part of the user address space, or lpProviderDllPathLen is too small.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.
Import Library: Link with ws2_32.lib.

See Also

WSCInstallProvider, WSCEnumProtocols


WSCInstallNameSpace

The WSCInstallNameSpace function installs 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.

int WSCInstallNameSpace (
  LPWSTR lpszIdentifier,
  LPWSTR lpszPathName,
  DWORD dwNameSpace,
  DWORD dwVersion,
  LPGUID lpProviderId
);

Parameters

lpszIdentifier
[in] A pointer to string that identifies the provider for use in the GUI.
lpszPathName
[in] A pointer to a string that contains the path to the provider's DLL image. The string observes the usual rules for path resolution: this path can contain embedded environment strings (such as %SystemRoot%); and such environment strings are expanded whenever the WS2_32.DLL needs to subsequently load the provider DLL on behalf of an application. After any embedded environment strings are expanded, the WS2_32.DLL passes the resulting string into the LoadLibrary function to load the provider into memory. For more information, see LoadLibrary.
dwNameSpace
[in] A descriptor that specifies the name space supported by this provider.
dwVersion
[in] A descriptor that specifies the version number of the provider.
lpProviderId
[in] A unique identifier for this provider. This GUID should be generated by UUIDGEN.EXE.

Remarks

The name space configuration functions do not affect applications that are already running. Newly installed name space providers will not be visible to applications nor will the changes in a name space provider's activation state. Applications launched after the call to WSCInstallNameSpace will see the changes.

Return Values

If no error occurs, the WSCInstallNameSpace function returns NO_ERROR (zero). Otherwise, it returns SOCKET_ERROR if the function fails, and it must set the appropriate error code using SetLastError.

Error Codes

WSAEACCESS The calling routine does not have sufficient privileges to install a name space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.
Import Library: Link with ws2_32.lib.


WSCInstallProvider

The WSCInstallProvider function installs the specified transport provider into the system configuration database.

int WSCInstallProvider (
  const LPGUID lpProviderId,
  const LPWSTR lpszProviderDllPath,
  const LPWSAPROTOCOL_INFOW lpProtocolInfoList,
  DWORD dwNumberOfEntries,
  LPINT lpErrno
);

Parameters

lpProviderId
[in] A pointer to a provider-selected, globally unique identifier (GUID).
lpszProviderDllPath
[in] A pointer to a string containing the load path to the provider's DLL. This string observes the usual rules for path resolution, and can contain embedded environment strings (such as %SystemRoot%); and such environment strings are expanded whenever the WS2_32.DLL needs to subsequently load the provider DLL on behalf of an application. After any embedded environment strings are expanded, the WS2_32.DLL passes the resulting string into the LoadLibrary function to load the provider into memory. For more information, see LoadLibrary.
lpProtocolInfoList
[in] Points to an array of WSAPROTOCOL_INFOW structures. Each structure defines a protocol,address_family, and socket_type supported by the provider.
dwNumberOfEntries
[in] Contains the number of entries in the lpProtocolInfoList array.
lpErrno
[out] A pointer to the error code.

Remarks

This routine creates the necessary common Windows Sockets 2 configuration information for the specified provider. It is applicable to base protocols, layered protocols and protocol chains. After this routine completes successfully, the protocol information provided in lpProtocolInfoList will be returned by the WSAEnumProtocols. Note that in Win32 environments, only instances of the WS2_32.DLL created after a successful completion of this function will include the new entries in WSAEnumProtocols.

Any file installation or service provider specific configuration must be performed by the caller.

Return Values

If no error occurs, WSCInstallProvider returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAEFAULT One of more of the arguments is not in a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.
Import Library: Link with ws2_32.lib.

See Also

WSCDeinstallProvider, WSCEnumProtocols


WSCUninstallNameSpace

The WSCUninstallNameSpace function uninstalls the indicated name space provider.

int WSCUninstallNameSpace (
  LPGUID lpProviderId
);

Parameters

lpProviderId
[in] The unique identifier for this provider.

Remarks

The name space configuration functions do not affect applications that are already running. Newly installed name space providers will not be visible to applications nor will the changes in a name space provider's activation state. Applications launched after the call to WSCUninstallNameSpace will see the changes.

Return Values

If no error occurs, WSCUninstallNameSpace returns NO_ERROR (zero). Otherwise, it returns SOCKET_ERROR and must set the appropriate error code using SetLastError.

Error Codes

WSAEINVAL the specified name space provider ID is invalid.


WSCWriteProviderOrder

The WSCWriteProviderOrder function is used to reorder the available transport providers. The order of the protocols determines the priority of a protocol when being enumerated or selected for us.

int WSCWriteProviderOrder (
  LPDWORD lpwdCatalogEntryId,
  DWORD dwNumberOfEntries
);

Parameters

lpwdCatalogEntryId
[in] An array of CatalogEntryId elements found in the WSAPROTOCOL_INFO structure. The order of the CatalogEntryId elements is the new priority ordering for the protocols.
dwNumberOfEntries
[in] The number of elements in the lpwdCatalogEntryId array.

Remarks

The order in which transport service providers are initially installed governs the order in which they are enumerated through WSCEnumProtocols at the service provider interface, or through WSAEnumProtocols at the application interface. More importantly, this order also governs the order in which protocols and service providers are considered when a client requests creation of a socket based on its address family, type, and protocol identifier. Windows Sockets 2 includes an applet called SPORDER.EXE that allows the catalog of installed protocols to be re-ordered interactively after protocols have already been installed. Windows Sockets 2 also includes an auxiliary DLL, SPORDER.DLL, that exports this procedural interface for re-ordering protocols. This interface can be imported by linking with SPORDER.LIB.

Here are scenarios in which the WSCWriteProviderOrder function can fail.

  • The dwNumberOfEntries parameter 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 one 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 function.

Return Values

The function returns ERROR_SUCCESS (0) if the routine is successful. Otherwise it returns a specific error code as follows.

Error Codes

WSAEINVAL | Input parameters were bad, no action was taken.
ERROR_BUSY | The routine is being called by another thread or process.
(other) | The routine may return any registry error code.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in sporder.h.
Import Library: Included as a resource in sporder.dll.


WSPAccept

The WSPAccept function conditionally accepts a connection based on the return value of a condition function, and optionally creates or joins a socket group.

SOCKET WSPAccept (
  SOCKET s,
  struct sockaddr FAR * addr,
  LPINT addrlen,
  LPCONDITIONPROC lpfnCondition,
  DWORD dwCallbackData,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket that is listening for connections after a WSPListen.
addr
[out] An optional pointer to a buffer that receives the address of the connecting entity, as known to the service provider. The exact format of the addr argument is determined by the address family established when the socket was created.
addrlen
[in/out] An optional pointer to an integer that contains the length of the addr parameter.
lpfnCondition
[in] The procedure instance address of an optional condition function furnished by the Windows Sockets application. This function is used in the accept or reject decision based on the caller information passed in as parameters. Optionally, it is used to create or join a socket group by assigning an appropriate value to the result parameter, g, of this function.
dwCallbackData
[in] Callback data to be passed back to the Windows Socket 2 client as the value of the dwCallbackData parameter of the condition function. This parameter is not interpreted by the service provider.
lpErrno
[out] A pointer to the error code.

Remarks

The WSPAccept function extracts the first connection on the queue of pending connections on socket s, and checks it against the condition function, provided the condition function is specified (that is, not NULL). The condition function must be executed in the same thread as this routine. If the condition function returns CF_ACCEPT, WSPAccept creates a new socket and performs any socket grouping as indicated by the result parameter, g, in the condition function. Newly created sockets have the same properties as the socket s, including network events registered with WSPAsyncSelect or with WSPEventSelect, but not including the listening socket's group ID, if any. As is described Descriptor Allocation, when new socket descriptors are allocated IFS providers must call WPUModifyIFSHandle and non-IFS providers must call WPUCreateSocketHandle.

If the condition function returns CF_REJECT, WSPAccept rejects the connection request. If the application's accept/reject decision cannot be made immediately, the condition function will return CF_DEFER to indicate that no decision has been made. No action about this connection request is to be taken by the service provider. When the application is ready to take action on the connection request, it will invoke WSPAccept again and return either CF_ACCEPT or CF_REJECT as a return value from the condition function.

For sockets that are in the (default) blocking mode, if no pending connections are present on the queue, WSPAccept blocks the caller until a connection is present. For sockets in a nonblocking mode, if this function is called when no pending connections are present on the queue, WSPAccept returns the error code WSAEWOULDBLOCK as described below. The accepted socket cannot be used to accept more connections. The original socket remains open.

The argument addr is a result parameter that is filled with the address of the connecting entity, as known to the service provider. The exact format of the addr parameter is determined by the address family in which the communication is occurring. The addrlen is a value-result parameter; it will initially contain the amount of space pointed to by addr. On return, it must contain the actual length (in bytes) of the address returned by the service provider. This call is used with connection-oriented socket types such as SOCK_STREAM. If addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned. Otherwise, these two parameters shall be filled in regardless of whether the condition function is specified or what it returns.

The prototype of the condition function is as follows:

int CALLBACK
ConditionFunc (
 IN       LPWSABUF lpCallerId,
 IN       LPWSABUF lpCallerData,
 IN OUT   LPQOS lpSQOS,
 IN OUT   LPQOS lpGQOS,
 IN       LPWSABUF lpCalleeId,
 IN       LPWSABUF lpCalleeData,
 OUT      GROUP FAR * g,
 IN       DWORD dwCallbackData
);

The lpCallerId and lpCallerData are value parameters that must contain the address of the connecting entity and any user data that was sent along with the connection request. If no caller ID or caller data is available, the corresponding parameter will be NULL. Many network protocols do not support connect-time caller data. Most conventional network protocols can be expected to support caller ID information at connection-request time. The buf part of the WSABUF pointed to by lpCallerId points to a SOCKADDR. The SOCKADDR is interpreted according to its address family (typically by casting the SOCKADDR to some type specific to the address family).

The lpSQOS parameter references the flow specifications for socket s specified by the caller, one for each direction, followed by any additional provider-specific parameters. The sending or receiving flow specification values will be ignored as appropriate for any unidirectional sockets. A NULL value for lpSQOS indicates that there is no caller supplied QOS and that no negotiation is possible. A non-NULL lpSQOS pointer indicates that a QOS negotiation is to occur or that the provider is prepared to accept the QOS request without negotiation.

Reserved for future use with socket groups: The lpGQOS parameter references the flow specifications for the socket group the caller is to create, one for each direction, followed by any additional provider-specific parameters. A NULL value for lpGQOS indicates no caller-supplied group QOS. QOS information can be returned if a QOS negotiation is to occur.

The lpCalleeId is a value parameter which contains the local address of the connected entity. The buf part of the WSABUF pointed to by lpCalleeId points to a SOCKADDR. The SOCKADDR is interpreted according to its address family (typically by casting the SOCKADDR to some type specific to the address family).

The lpCalleeData is a result parameter used by the condition function to supply user data back to the connecting entity. The storage for this data must be provided by the service provider. lpCalleeData->len initially contains the length of the buffer allocated by the service provider and pointed to by lpCalleeData->buf. A value of zero means passing user data back to the caller is not supported. The condition function will copy up to lpCalleeData->len bytes of data into lpCalleeData->buf, and then update lpCalleeData->len to indicate the actual number of bytes transferred. If no user data is to be passed back to the caller, the condition function will set lpCalleeData->len to zero. The format of all address and user data is specific to the address family to which the socket belongs.

Reserved for future use with socket groups: The result parameter g is assigned within the condition function to indicate the following actions:

if &g is an existing socket group ID, add s to this group, provided all the requirements set by this group are met; or

if &g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket group and have s as the first member; or

if &g = SG_CONSTRAINED_GROUP, create a constrained socket group and have s as the first member; or

if &g = zero, no group operation is performed.

Any set of sockets grouped together must be implemented by a single service provider. For unconstrained groups, any set of sockets can be grouped together. A constrained socket group can consist only of connection-oriented sockets, and requires that connections on all grouped sockets be to the same address on the same host. For newly created socket groups, the new group ID must be available for the Windows Sockets SPI client to retrieve by calling WSPGetSockOpt with option SO_GROUP_ID. A socket group and its associated ID remain valid until the last socket belonging to this socket group is closed. Socket group IDs are unique across all processes for a given service provider.

The dwCallbackData parameter value passed to the condition function is the value passed as the dwCallbackData parameter in the original WSPAccept call. This value is interpreted only by the Windows Sockets 2 client. This allows a client to pass some context information from the WSPAccept call site through to the condition function, which provides the condition function with any additional information required to determine whether to accept the connection or not. A typical usage is to pass a (suitably cast) pointer to a data structure containing references to application-defined objects with which this socket is associated.

Return Values

If no error occurs, WSPAccept returns a value of type SOCKET that is a descriptor for the accepted socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code is available in lpErrno.

Error Codes

WSAECONNREFUSED | The connection request was forcefully rejected as indicated in the return value of the condition function (CF_REJECT).
WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The addrlen argument is too small or the lpfnCondition is not part of the user address space.
WSAEINTR | The (blocking) call was canceled through WSPCancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress.
WSAEINVAL | WSPListen was not invoked prior to WSPAccept, parameter g specified in the condition function is not a valid value, the source address of the incoming connection request is not consistent with that of the constrained group the parameter g is referring to, the return value of the condition function is not a valid one, or any case where the specified socket is in an invalid state.
WSAEMFILE | The queue is nonempty upon entry to WSPAccept and there are no socket descriptors available.
WSAENOBUFS | No buffer space is available.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The referenced socket is not a type that supports connection-oriented service.
WSATRY_AGAIN | The acceptance of the connection request was deferred as indicated in the return value of the condition function (CF_DEFER).
WSAEWOULDBLOCK | The socket is marked as nonblocking and no connections are present to be accepted.
WSAEACCES | The connection request that was offered has timed out or been withdrawn.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPAccept, WSPBind, WSPConnect, WSPGetSockOpt, WSPListen, WSPSelect, WSPSocket, WSPAsyncSelect, WSPEventSelect


WSPAddressToString

The WSPAddressToString function converts all components of a SOCKADDR structure into a human-readable numeric string representation of the address. This is used mainly for display purposes.

int WSPAddressToString (
  LPSOCKADDR lpsaAddress,
  DWORD dwAddressLength,
  LPWSAPROTOCOL_INFOW lpProtocolInfo,
  LPWSTR lpszAddressString,
  LPDWORD lpdwAddressStringLength,
  LPINT lpErrno
);

Parameters

lpsaAddress
[in] Points to a SOCKADDR structure to translate into a string.
dwAddressLength
[in] The length of the Address SOCKADDR.
lpProtocolInfo
[in] (required) The WSAPROTOCOL_INFO structure associated with the provider that will do the translation.
lpszAddressString
[out] A buffer which receives the human-readable address string.
lpdwAddressStringLength
[in/out] The length of the AddressString buffer. Returns the length of the string actually copied into the buffer. If the supplied buffer is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated with the required size in bytes.
lpErrno
[out] A pointer to the error code.

Layered Service Provider Considerations

A layered service provider supplies an implementation of this function, but it is also a client of this function if and when it calls WSPAddressToString of the next layer in the protocol chain. Some special considerations apply to this function's lpProtocolInfo parameter as it is propagated down through the layers of the protocol chain.

If the next layer in the protocol chain is another layer then when the next layer's WSPAddressToString is called, this layer must pass to the next layer a lpProtocolInfo that references the same unmodified WSAPROTOCOL_INFO structure with the same unmodified chain information. However, if the next layer is the base protocol (i.e., the last element in the chain), this layer performs a substitution when calling the base provider's WSPAddressToString. In this case, the base provider's WSAPROTOCOL_INFO structure should be referenced by the lpProtocolInfo parameter.

One vital benefit of this policy is that base service providers do not have to be aware of protocol chains.

This same propagation policy applies when propagating a WSAPROTOCOL_INFO structure through a layered sequence of other functions such as WSPDuplicateSocket, WSPStartup, WSPSocket, or WSPStringToAddress.

Return Values

If no error occurs, WSPAddressToString returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAEFAULT | The specified AddressString buffer is too small. Pass in a larger buffer.
WSA_EINVAL | The specified Address is not a valid socket address, or its address family is not supported by the provider, or the specified lpProtocolInfo did not refer to a WSAPROTOCOL_INFO structure supported by the provider.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


WSPAsyncSelect

The WSPAsyncSelect function requests Windows message-based event notification of network events for a socket.

int WSPAsyncSelect (
  SOCKET s,
  HWND hWnd,
  unsigned int wMsg,
  long lEvent,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying the socket for which event notification is required.
hWnd
[in] A handle identifying the window which should receive a message when a network event occurs.
wMsg
[in] The message to be sent when a network event occurs.
lEvent
[in] A bitmask which specifies a combination of network events in which the Windows Sockets SPI client is interested.
lpErrno
[out] A pointer to the error code.

This function is used to request that the service provider send a Window message to the client's window hWnd whenever it detects any of the network events specified by the lEvent parameter. The service provider should use the WPUPostMessage function to post the message. The message to be sent is specified by the wMsg parameter. The socket for which notification is required is identified by s.

This function automatically sets socket s to nonblocking mode, regardless of the value of lEvent. See WSPIoctl about how to set the socket back to blocking mode.

The lEvent parameter is constructed by or'ing any of the values specified in the following list.

Value | Meaning
FD_READ | Issue notification of readiness for reading
FD_WRITE | Issue notification of readiness for writing
FD_OOB | Issue notification of the arrival of out-of-band data
FD_ACCEPT | Issue notification of incoming connections
FD_CONNECT | Issue notification of completed connection
FD_CLOSE | Issue notification of socket closure
FD_QOS | Issue notification of socket Quality of Service (QOS) changes
FD_GROUP_QOS | Reserved for future use with socket groups: Issue notification of socket group Quality of Service (QOS) changes
FD_ROUTING _INTERFACE_CHANGE | Issue notification of routing interface change for the specified destination
FD_ADDRESS_LIST _CHANGE | Issue notification of local address list change for the socket's protocol family

Invoking WSPAsyncSelect for a socket cancels any previous WSPAsyncSelect or WSPEventSelect for the same socket. For example, to receive notification for both reading and writing, the Windows Sockets SPI client must call WSPAsyncSelect with both FD_READ and FD_WRITE, as follows:

rc = WSPAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE, &error);

It is not possible to specify different messages for different events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE events will be reported with message wMsg2:

rc = WSPAsyncSelect(s, hWnd, wMsg1, FD_READ, &error);
rc = WSPAsyncSelect(s, hWnd, wMsg2, FD_WRITE, &error);

To cancel all notification (for example, to indicate that the service provider should send no further messages related to network events on the socket) lEvent will be set to zero.

rc = WSPAsyncSelect(s, hWnd, 0, 0, &error);

Since a socket created by WSPAccept has the same properties as the listening socket used to accept it, any WSPAsyncSelect events set for the listening socket apply to the accepted socket. For example, if a listening socket has WSPAsyncSelect events FD_ACCEPT, FD_READ, and FD_WRITE, then any socket accepted on that listening socket will also have FD_ACCEPT, FD_READ, and FD_WRITE events with the same wMsg value used for messages. If a different wMsg or events are needed, the Windows Sockets SPI client must call WSPAsyncSelect, passing the accepted socket and the new information.

When one of the nominated network events occurs on the specified socket s, the service provider uses WPUPostMessage to send message wMsg to the Windows Sockets SPI client's window hWnd. The wParam argument identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code. The error code be any error as defined in WS2SPI.H.

The possible network event codes which can be indicated are as follows:

Value | Meaning
FD_READ | Socket s ready for reading
FD_WRITE | Socket s ready for writing
FD_OOB | Out-of-band data ready for reading on socket s
FD_ACCEPT | Socket s ready for accepting a new incoming connection
FD_CONNECT | Connection initiated on socket s completed
FD_CLOSE | Connection identified by socket s has been closed
FD_QOS | Quality of Service associated with socket s has changed
FD_GROUP_QOS | Reserved for future use with socket groups: Quality of Service associated with the socket group to which s belongs has changed
FD_ROUTING _INTERFACE_CHANGE | Local interface that should be used to send to the specified destination has changed
FD_ADDRESS_LIST _CHANGE | The list of addresses of the socket's protocol family to which the Windows Socket SPI client can bind has changed

Return Values

The return value is zero if the Windows Sockets SPI client's declaration of interest in the network event set was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Comments

Although WSPAsyncSelect can be called with interest in multiple events, the service provider issues the same Windows message for each event.

A Windows Sockets 2 provider shall not continually flood a Windows Sockets SPI client with messages for a particular network event. Having successfully posted notification of a particular event to a Windows Sockets SPI client window, no further message(s) for that network event will be posted to the Windows Sockets SPI client window until the Windows Sockets SPI client makes the function call which implicitly re-enables notification of that network event.

Event | Re-enabling function
FD_READ | WSPRecv or WSPRecvFrom
FD_WRITE | WSPSend or WSPSendTo
FD_OOB | WSPRecv or WSPRecvFrom
FD_ACCEPT | WSPAccept unless the error code returned is WSATRY_AGAIN indicating that the condition function returned CF_DEFER
FD_CONNECT | NONE
FD_CLOSE | NONE
FD_QOS | WSPIoctl with SIO_GET_QOS
FD_GROUP_QOS | Reserved for future use with socket groups: WSPIoctl with SIO_GET_GROUP_QOS
FD_ROUTING _INTERFACE_CHANGE | WSPIoctl with command SIO_ROUTING_INTERFACE_CHANGE
FD_ADDRESS_LIST _CHANGE | WSPIoctl with command SIO_ADDRESS_LIST_CHANGE

Any call to the re-enabling routine, even one which fails, results in re-enabling of message posting for the relevant event.

For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is "level-triggered." This means that if the re-enabling routine is called and the relevant condition is still met after the call, a WSPAsyncSelect message is posted to the Windows Sockets SPI client.

The FD_QOS and FD_GROUP_QOS events are considered edge triggered. A message will be posted exactly once when a QOS change occurs. Further messages will not be forthcoming until either the provider detects a further change in QOS or the Windows Sockets SPI client renegotiates the QOS for the socket.

The FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events are considered "edge triggered" as well. A message will be posted exactly once when a change occurs after the Windows Socket 2 SPI client has request the notification by issuing WSPIoctl with SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE correspondingly. Further messages will not be forthcoming until the SPI client reissues the IOCTL and another change is detected since the IOCTL has been issued.

If any event has already happened when the Windows Sockets SPI client calls WSPAsyncSelect or when the re-enabling function is called, then a message is posted as appropriate. For example, consider the following sequence: 1) a SPI client calls WSPListen, 2) a connect request is received but not yet accepted, 3) the Windows Sockets SPI client calls WSPAsyncSelect specifying that it wants to receive FD_ACCEPT messages for the socket. Due to the persistence of events, the Windows Sockets service provider posts an FD_ACCEPT message immediately.

The FD_WRITE event is handled slightly differently. An FD_WRITE message is posted when a socket is first connected with WSPConnect (after FD_CONNECT, if also registered) or accepted with WSPAccept, and then after a WSPSend or WSPSendTo fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, a Windows Sockets SPI client can assume that sends are possible starting from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a failure the Windows Sockets SPI client will be notified that sends are again possible with an FD_WRITE message.

The FD_OOB event is used only when a socket is configured to receive out-of-band data separately. If the socket is configured to receive out-of-band data in-line, the out-of-band (expedited) data is treated as normal data and the Windows Sockets SPI client must register an interest in FD_READ events, not FD_OOB events.

The error code in an FD_CLOSE message indicates whether the socket close was graceful or abortive. If the error code is zero, then the close was graceful; if the error code is WSAECONNRESET, then the socket's virtual circuit was reset. This only applies to connection-oriented sockets such as SOCK_STREAM.

The FD_CLOSE message is posted when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means that the FD_CLOSE is posted when the connection goes into the TIME WAIT or CLOSE WAIT states. This results from the remote end performing a WSPShutdown on the send side or a WSPCloseSocket. FD_CLOSE shall only be posted after all data is read from a socket.

In the case of a graceful close, the service provider should only send an FD_CLOSE message to indicate virtual circuit closure after all the received data has been read. It should not send an FD_READ message to indicate this condition.

The FD_QOS or FD_GROUP_QOS message is posted when any field in the flow specification associated with socket s or the socket group that s belongs to has changed, respectively. The service provider must update the QOS information available to the client through WSPIoctl with SIO_GET_QOS and/or SIO_GET_GROUP_QOS.

The FD_ROUTING_INTERFACE_CHANGE message is posted when the local interface that should be used to reach the destination specified in WSPIoctl with SIO_ROUTING_INTERFACE_CHANGE changes AFTER such IOCTL has been issued.

The FD_ADDRESS_LIST_CHANGE message is posted when the list of addresses to which the Windows Socket 2 SPI client can bind changes AFTER WSPIoctl with SIO_ADDRESS_LIST_CHANGE has been issued.

Here is a summary of events and conditions for each asynchronous notification message:

  • FD_READ:
    1. when WSPAsyncSelect is called, if there is data currently available to receive,
    2. when data arrives, if FD_READ not already posted,
    3. after WSPRecv or WSPRecvfrom called (with or without MSG_PEEK), if data is still available to receive.

Note When WSPSetSockOpt SO_OOBINLINE is enabled, "data" includes both normal data and out-of-band (OOB) data in the instances noted above.

  • FD_WRITE:
    1. when WSPAsyncSelect called, if a WSPSend or WSPSendTo is possible,
    2. after WSPConnect or WSPAccept called, when connection established,
    3. after WSPSend or WSPSendTo fail with WSAEWOULDBLOCK, when WSPSend or WSPSendTo are likely to succeed,
    4. after WSPBind on a datagram socket. FD_WRITE may or may not occur at this time (implementation dependent). In any case, a connectionless socket is always writeable immediately after WSPBind.
  • FD_OOB: Only valid when WSPSetSockOpt SO_OOBINLINE is disabled (default).
    1. when WSPAsyncSelect called, if there is OOB data currently available to receive with the MSG_OOB flag,
    2. when OOB data arrives, if FD_OOB not already posted,
    3. after WSPRecv or WSPRecvfrom called with or without MSG_OOB flag, if OOB data is still available to receive.
  • FD_ACCEPT:
    1. when WSPAsyncSelect called, if there is currently a connection request available to accept,
    2. when a connection request arrives, if FD_ACCEPT not already posted,
    3. after WSPAccept called, if there is another connection request available to accept.
  • FD_CONNECT:
    1. when WSPAsyncSelect called, if there is currently a connection established,
    2. after WSPConnect called, when connection is established (even when WSPConnect succeeds immediately, as is typical with a datagram socket, and even when it fails immediately).
    3. after WSAJoinLeaf called, when join operation completes.
    4. after connect, WSAConnect, or WSAJoinLeaf was called with a nonblocking, connection-oriented socket. The initial operation returned with a specific error of WSAEWOULDBLOCK, but the network operation went ahead. Whether the operation eventually succeeds or not, when the outcome has been determined, FD_CONNECT happens. The client should check the error code to determine whether the outcome was success or failure.
  • FD_CLOSE: Only valid on connection-oriented sockets (for example, SOCK_STREAM)
    1. when WSPAsyncSelect called, if socket connection has been closed,
    2. after remote system initiated graceful close, when no data currently available to receive (note: if data has been received and is waiting to be read when the remote system initiates a graceful close, the FD_CLOSE is not delivered until all pending data has been read),
    3. after local system initiates graceful close with WSPShutdown and remote system has responded with "End of Data" notification (for example, TCP FIN), when no data currently available to receive,
    4. when remote system terminates connection (for example, sent TCP RST), and lParam will contain WSAECONNRESET error value.

      Note FD_CLOSE is not posted after WSPClosesocket is called.

  • FD_QOS Reserved for future use with socket groups:
    1. when WSPAsyncSelect called, if the QOS associated with the socket has been changed,
    2. after WSPIoctl with SIO_GET_QOS called, when the QOS is changed.
  • FD_GROUP_QOS:
    1. when WSPAsyncSelect called, if the group QOS associated with the socket has been changed,
    2. after WSPIoctl with SIO_GET_GROUP_QOS called, when the group QOS is changed.
  • FD_ROUTING_INTERFACE_CHANGE:
    1. after WSPIoctl with SIO_ROUTING_INTERFACE_CHANGE called, when the local interface that should be used to reach the destination specified in the IOCTL changes.
  • FD_ADDRESS_LIST_CHANGE:
    1. after WSPIoctl with SIO_ADDRESS_LIST_CHANGE called, when the list of local addresses to which the Windows Socket 2 SPI client can bind changes.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that one of the specified parameters was invalid such as the window handle not referring to an existing window, or the specified socket is in an invalid state.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor is not a socket.

Additional error codes can be set when the service provider issues a message to a Windows Sockets SPI client's window. This error code is embedded in the lParam field of the message. Possible error codes for each network event are:

Event: FD_CONNECT

Error Code | Meaning
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to connect was forcefully rejected.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAEFAULT | The namelen argument is incorrect.
WSAEINVAL | The socket is already bound to an address.
WSAEISCONN | The socket is already connected.
WSAEMFILE | No more file descriptors are available.
WSAENOBUFS | No buffer space is available. The socket cannot be connected.
WSAENOTCONN | The socket is not connected.
WSAETIMEDOUT | Attempt to connect timed out without establishing a connection.

Event: FD_CLOSE

Error Code | Meaning
WSAENETDOWN | The network subsystem has failed.
WSAECONNRESET | The connection was reset by the remote side.
WSAECONNABORTED | The connection was terminated due to a time-out or other failure.

Event: FD_READ

Event: FD_WRITE

Event: FD_OOB

Event: FD_ACCEPT

Event: FD_QOS

Event: FD_GROUP_QOS

Event: FD_ADDRESS_LIST_CHANGE

Error Code | Meaning
WSAENETDOWN | The network subsystem has failed.

Event: FD_ROUTING_INTERFACE_CHANGE

Error Code | Meaning
WSAENETUNREACH | The specified destination is no longer reachable
WSAENETDOWN | The network subsystem has failed.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPSelect


WSPBind

The WSPBind function associates a local address (that is, name) with a socket.

int WSPBind (
  SOCKET s,
  const struct sockaddr FAR * name,
  int namelen,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying an unbound socket.
name
[in] The address to assign to the socket. The SOCKADDR structure is defined as follows:
sockaddr {
    _short    sa_family;
    char       sa_data[14];
    };

Except for the sa_family field, SOCKADDR contents are expressed in network byte order. In Windows Sockets 2, the name parameter is not strictly interpreted as a pointer to a SOCKADDR structure. It is cast this way for Windows Sockets compatibility. The actual structure is interpreted differently in the context of different address families. The only requirements are that the first u_short is the address family and the total size of the memory buffer in bytes is namelen

namelen
[in] The length of the name.
lpErrno
[out] A pointer to the error code.

Remarks

This routine is used on an unconnected connectionless or connection-oriented socket, before subsequent calls to WSPConnect or WSPListen. When a socket is created with WSPSocket, it exists in a name space (address family), but it has no name or local address assigned. WSPBind establishes the local association of the socket by assigning a local name to an unnamed socket.

As an example, in the Internet address family, a name consists of three parts: the address family, a host address, and a port number which identifies the Windows Sockets SPI client. In Windows Sockets 2, the name parameter is not strictly interpreted as a pointer to a "SOCKADDR" structure. Service providers are free to regard it as a pointer to a block of memory of size namelen. The first two bytes in this block (corresponding to "sa_family" in the "SOCKADDR" declaration) must contain the address family that was used to create the socket. Otherwise, the error WSAEFAULT shall be indicated.

If a Windows Sockets 2 SPI client does not care what local address is assigned to it, it will specify the manifest constant value ADDR_ANY for the sa_data field of the name parameter. This instructs the service provider to use any appropriate network address. For TCP/IP, if the port is specified as zero, the service provider will assign a unique port to the Windows Sockets SPI client with a value between 1024 and 5000. The SPI client can use WSPGetSockName after WSPBind to learn the address and the port that has been assigned to it, but note that if the Internet address is equal to INADDR_ANY, WSPGetSockOpt will not necessarily be able to supply the address until the socket is connected, since several addresses can be valid if the host is multihomed.

Return Values

If no error occurs, WSPBind returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | Some process on the machine has already bound to the same fully-qualified address (for example, IP address and port in the af_inet case) and the socket has not been marked to allow address re-use with SO_REUSEADDR (See the SO_REUSEADDR socket option under WSPSetSockOpt.)
WSAEADDRNOTAVAIL | The specified address is not a valid address for this machine.
WSAEFAULT | The name or the namelen argument is not a valid part of the user address space, the namelen argument is too small, the name argument contains incorrect address format for the associated address family, or the first two bytes of the memory block specified by name does not match the address family associated with the socket descriptor s.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAEINVAL | The socket is already bound to an address.
WSAENOBUFS | Not enough buffers available, too many connections.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPConnect, WSPListen, WSPGetSockName, WSPSetSockOpt, WSPSocket


WSPCancelBlockingCall

The WSPCancelBlockingCall function cancels a blocking call which is currently in progress.

int WSPCancelBlockingCall (
  LPINT lpErrno
);

Parameters

lpErrno
[out] A pointer to the error code.

Remarks

This function cancels any outstanding blocking operation for this thread. It is normally used in two situations:

  1. A Windows Sockets SPI client is processing a message which has been received while a service provider is implementing pseudo blocking. In this case, WSAIsBlocking will be true.
  2. A blocking call is in progress, and the Windows Sockets service provider has called back to the Windows Sockets SPI client's "blocking hook" function (through the callback function retrieved from WPUQueryBlockingCallback), which in turn is invoking this function. Such a situation might arise, for instance, in implementing a Cancel option for an operation which require an extended time to complete.

In each case, the original blocking call will terminate as soon as possible with the error WSAEINTR. (In (1), the termination will not take place until Windows message scheduling has caused control to revert back to the pseudo blocking routine in Windows Sockets. In (2), the blocking call will be terminated as soon as the blocking hook function completes.)

In the case of a blocking WSPConnect operation, Windows Sockets will terminate the blocking call as soon as possible, but it cannot be possible for the socket resources to be released until the connection has completed (and then been reset) or timed out. This is likely to be noticeable only if the Windows Sockets SPI client immediately tries to open a new socket (if no sockets are available), or to WSPConnect to the same peer.

Canceling an WSPAccept or a WSPSelect call does not adversely impact the sockets passed to these calls. Only the particular call fails; any operation that was legal before the cancel is legal after the cancel, and the state of the socket is not affected in any way.

Canceling any operation other than WSPAccept and WSPSelect can leave the socket in an indeterminate state. If a Windows Sockets SPI client cancels a blocking operation on a socket, the only operation that the Windows Sockets SPI client can depend on being able to perform on the socket is a call to WSPCloseSocket, although other operations can work on some Windows Sockets service providers. If a Windows Sockets SPI client requires maximum portability, it must be careful not to depend on performing operations after a cancel. A Windows Sockets SPI client can reset the connection by setting the time-out on SO_LINGER to zero and calling WSPCloseSocket.

If a cancel operation compromised the integrity of a SOCK_STREAM's data stream in any way, the Windows Sockets provider will reset the connection and fail all future operations other than WSPCloseSocket with WSAECONNABORTED.

Return Values

The value returned by WSPCancelBlockingCall is zero if the operation was successfully canceled. Otherwise, the value SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Comments

Note it is acceptable for WSPCancelBlockingCall to return successfully if the blocking network operation completes prior to being canceled. In this case, the blocking operation will return successfully as if WSPCancelBlockingCall had never been called. The only way for the Windows Sockets SPI client to know with certainty that an operation was actually canceled is to check for a return code of WSAEINTR from the blocking call.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that there is no outstanding blocking call.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


WSPCleanup

The WSPCleanup function terminates use of the Windows Sockets service provider.

int WSPCleanup (
  LPINT lpErrno
);

Parameters

lpErrno
[out] A pointer to the error code.

Remarks

The Windows Sockets 2 SPI client is required to perform a successful WSPStartup call before it can use Windows Sockets service providers. When it has completed the use of Windows Sockets service providers, the SPI client will call WSPCleanup to deregister itself from a Windows Sockets service provider and allow the service provider to free any resources allocated on behalf of the Windows Sockets 2 client. It is permissible for SPI clients to make more than one WSPStartup call. For each WSPStartup call a corresponding WSPCleanup call will also be issued. Only the final WSPCleanup for the service provider does the actual cleanup; the preceding calls simply decrement an internal reference count in the Windows Sockets service provider.

When the internal reference count reaches zero and actual cleanup operations commence, any pending blocking or asynchronous calls issued by any thread in this process are canceled without posting any notification messages or signaling any event objects. Any pending overlapped send and receive operations (WSPSend/WSPSendTo/WSPRecv/WSPRecvFrom with an overlapped socket) issued by any thread in this process are also canceled without setting the event object or invoking the completion routine, if specified. In this case, the pending overlapped operations fail with the error status WSA_OPERATION_ABORTED. Any sockets open when WSPCleanup is called are reset and automatically deallocated as if WSPClosesocket was called; sockets which have been closed with WSPCloseSocket but which still have pending data to be sent are not affected—the pending data is still sent.

This function should not return until the service provider DLL is prepared to be unloaded from memory. In particular, any data remaining to be transmitted must either already have been sent or be queued for transmission by portions of the transport stack that will not be unloaded from memory along with the service provider's DLL.

Return Values

The return value is zero if the operation has been successfully initiated. Otherwise, the value SOCKET_ERROR is returned, and a specific error number is available in lpErrno.

Comments

A Windows Sockets service provider must be prepared to deal with a process which terminates without invoking WSPCleanup (for example, as a result of an error). A Windows Sockets service provider must ensure that WSPCleanup leaves things in a state in which the WS2_32.DLL can immediately invoke WSPStartup to re-establish Windows Sockets usage.

Error Codes

WSANOTINITIALISED | A successful WSPStartup must occur before using this function.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | The provider ID given to the name space provider is not managed by the name space provider.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPStartup, WSPClosesocket, WSPShutdown


WSPCloseSocket

The WSPCloseSocket function closes a socket.

int WSPCloseSocket (
  SOCKET s,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
lpErrno
[out] A pointer to the error code.

Remarks

This function closes a socket. More precisely, it releases the socket descriptor s, so that further references to s should fail with the error WSAENOTSOCK. If this is the last reference to an underlying socket, the associated naming information and queued data are discarded. Any blocking or asynchronous calls pending on the socket (issued by any thread in this process) are canceled without posting any notification messages. Any pending overlapped operations issued by any thread in this process are also canceled. Whatever completion action was specified for these overlapped operations is performed (for example, event, completion routine, or completion port). In this case, the pending overlapped operations fail with the error status WSA_OPERATION_ABORTED. FD_CLOSE will not be posted after WSPCloseSocket is called.

WSPClosesocket behavior is summarized as follows:

  • if SO_DONTLINGER enabled (the default setting) WSPCloseSocket returns immediately, and connection is gracefully closed "in the background"
  • if SO_LINGER enabled with a zero time-out: WSPCloseSocket returns immediately, and connection is reset/terminated
  • if SO_LINGER enabled with nonzero time-out:

    – with blocking socket WSPCloseSocket blocks until all data sent or time-out expires

    – with nonblocking socket returns immediately indicating failure

The semantics of WSPCloseSocket are affected by the socket options SO_LINGER and SO_DONTLINGER as follows:

Option | Interval | Type of close | Wait for close?
SO_DONTLINGER | Do not care | Graceful | No
SO_LINGER | Zero | Hard | No
SO_LINGER | Nonzero | Graceful | Yes

If SO_LINGER is set (that is, the l_onoff field of the linger structure is nonzero) and the time-out interval, l_linger, is zero, WSPClosesocket is not blocked even if queued data has not yet been sent or acknowledged. This is called a "hard" or "abortive" close, because the socket's virtual circuit is reset immediately, and any unsent data is lost. Any WSPRecv call on the remote side of the circuit will fail with WSAECONNRESET.

If SO_LINGER is set with a nonzero time-out interval on a blocking socket, the WSPClosesocket call blocks on a blocking socket until the remaining data has been sent or until the time-out expires. This is called a graceful disconnect. If the time-out expires before all data has been sent, the service provider should terminate the connection before WSPClosesocket returns.

Enabling SO_LINGER with a nonzero time-out interval on a nonblocking socket is not recommended. In this case, the call to WSPClosesocket will fail with an error of WSAEWOULDBLOCK if the close operation cannot be completed immediately. If WSPClosesocket fails with WSAEWOULDBLOCK the socket handle is still valid, and a disconnect is not initiated. The Windows Sockets SPI client must call WSPClosesocket again to close the socket, although WSPClosesocket can continue to fail unless the Windows Sockets SPI client disables SO_DONTLINGER, enables SO_LINGER with a zero time-out, or calls WSPShutdown to initiate closure.

If SO_DONTLINGER is set on a stream socket (that is, the l_onoff field of the linger structure is zero), the WSPClosesocket call will return immediately and does not get WSAEWOULDBLOCK, whether the socket is blocking or nonblocking. However, any data queued for transmission will be sent if possible before the underlying socket is closed. This is called a graceful disconnect and is the default behavior. Note that in this case the Windows Sockets provider is allowed to retain any resources associated with the socket until such time as the graceful disconnect has completed or the provider terminates the connection due to an inability to complete the operation in a provider-determined amount of time. This can affect Windows Sockets clients which expect to use all available sockets. This is the default behavior (SO_DONTLINGER is set by default)

Return Values

If no error occurs, WSPCloseSocket returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor is not a socket.
WSAEWOULDBLOCK | The socket is marked as nonblocking and SO_LINGER is set to a nonzero timeout value.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPAccept, WSPSocket, WSPIoctl, WSPSetSockOpt


WSPConnect

The WSPConnect function establishes a connection to a peer, exchanges connect data, and specifies needed quality of service based on the supplied flow specification.

int WSPConnect (
  SOCKET s,
  const struct sockaddr FAR * name,
  int namelen,
  LPWSABUF lpCallerData,
  LPWSABUF lpCalleeData,
  LPQOS lpSQOS,
  LPQOS lpGQOS,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying an unconnected socket.
name
[in] The name of the peer to which the socket is to be connected.
namelen
[in] The length of the name.
lpCallerData
[in] A pointer to the user data that is to be transferred to the peer during connection establishment.
lpCalleeData
[out] A pointer to a buffer into which any user data received from the peer during connection establishment can be copied.
lpSQOS
[in] A pointer to the flow specifications for socket s, one for each direction.
lpGQOS
[in] Reserved for future use with socket groups: A pointer to the flow specifications for the socket group (if applicable).
lpErrno
[out] A pointer to the error code.

Remarks

This function is used to create a connection to the specified destination, and to perform a number of other ancillary operations that occur at connect time as well. If the socket, s, is unbound, unique values are assigned to the local association by the system, and the socket is marked as bound.

For connection-oriented sockets (for example, type SOCK_STREAM), an active connection is initiated to the specified host using name (an address in the name space of the socket; for a detailed description, please see WSPBind). When this call completes successfully, the socket is ready to send/receive data. If the address field of the name structure is all zeroes, WSPConnect will return the error WSAEADDRNOTAVAIL. Any attempt to re-connect an active connection will fail with the error code WSAEISCONN.

For connection-oriented, nonblocking sockets it is often not possible to complete the connection immediately. In such a case, this function returns with the error WSAEWOULDBLOCK but the operation proceeds. When the success or failure outcome becomes known, it may be reported in one of several ways depending on how the client registers for notification. If the client uses WSPSelect success is reported in the writefds set and failure is reported in the exceptfds set. If the client uses WSPAsyncSelect or WSPEventSelect, the notification is announced with FD_CONNECT and the error code associated with the FD_CONNECT indicates either success or a specific reason for failure.

For a connectionless socket (for example, type SOCK_DGRAM), the operation performed by WSPConnect is to establish a default destination address so that the socket can be used with subsequent connection-oriented send and receive operations (WSPSend,WSPRecv ). Any datagrams received from an address other than the destination address specified will be discarded. If the address field of the name structure is all zeroes, the socket will be "dis-connected" — the default remote address will be indeterminate, so WSPSend and WSPRecv calls will return the error code WSAENOTCONN, although WSPSendTo and WSPRecvFrom can still be used. The default destination can be changed by simply calling WSPConnect again, even if the socket is already "connected". Any datagrams queued for receipt are discarded if name is different from the previous WSPConnect.

For connectionless sockets, name can indicate any valid address, including a broadcast address. However, to connect to a broadcast address, a socket must have WSPSetSockOpt SO_BROADCAST enabled. Otherwise, WSPConnect will fail with the error code WSAEACCES.

On connectionless sockets, exchange of user to user data is not possible and the corresponding parameters will be silently ignored.

The Windows Sockets SPI client is responsible for allocating any memory space pointed to directly or indirectly by any of the parameters it specifies.

The lpCallerData is a value parameter which contains any user data that is to be sent along with the connection request. If lpCallerData is NULL, no user data will be passed to the peer. The lpCalleeData is a result parameter which will reference any user data passed back from the peer as part of the connection establishment. lpCalleeData->len initially contains the length of the buffer allocated by the Windows Sockets SPI client and pointed to by lpCalleeData->buf. lpCalleeData->len will be set to zero if no user data has been passed back. The lpCalleeData information will be valid when the connection operation is complete. For blocking sockets, this will be when the WSPConnect function returns. For nonblocking sockets, this will be after the FD_CONNECT notification has occurred. If lpCalleeData is NULL, no user data will be passed back. The exact format of the user data is specific to the address family to which the socket belongs and/or the applications involved.

At connect time, a Windows Sockets SPI client can use the lpSQOS and/or lpGQOS parameters to override any previous QOS specification made for the socket through WSPIoctl with either the SIO_SET_QOS or SIO_SET_GROUP_QOS opcodes.

lpSQOS specifies the flow specifications for socket s, one for each direction, followed by any additional provider-specific parameters. If either the associated transport provider in general or the specific type of socket in particular cannot honor the QOS request, an error will be returned as indicated below. The sending or receiving flow specification values will be ignored, respectively, for any unidirectional sockets. If no provider-specific parameters are supplied, the buf and len fields of lpSQOS->ProviderSpecific should be set to NULL and zero, respectively. A NULL value for lpSQOS indicates no application supplied QOS.

Reserved for future use with socket groups: lpGQOS specifies the flow specifications for the socket group (if applicable), one for each direction, followed by any additional provider-specific parameters. If no provider-specific parameters are supplied, the buf and len fields of lpGQOS->ProviderSpecific should be set to NULL and zero, respectively. A NULL value for lpGQOS indicates no application-supplied group QOS. This parameter will be ignored if s is not the creator of the socket group.

Comments

When connected sockets break (that is, become closed for whatever reason), they should be discarded and recreated. It is safest to assume that when things go awry for any reason on a connected socket, the Windows Sockets SPI client must discard and recreate the needed sockets in order to return to a stable point.

Return Values

If no error occurs, WSPConnect returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code is available in lpErrno.

On a blocking socket, the return value indicates success or failure of the connection attempt. If the return error code indicates the connection attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the Windows Sockets SPI client can call WSPConnect again for the same socket.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | The local address of the socket is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs at the time of bind, but could be delayed until this function if the bind was to a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be "committed" at the time of this function..
WSAEINTR | The (blocking) call was canceled through WSPCancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAEALREADY | A nonblocking WSPConnect call is in progress on the specified socket. In order to preserve backward compatibility, this error is reported as WSAEINVAL to Windows Sockets 1.1 applications that link to either WINSOCK.DLL or WSOCK32.DLL
WSAEADDRNOTAVAIL | The remote address is not a valid address (for example, ADDR_ANY).
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to connect was rejected.
WSAEFAULT | The name or the namelen argument is not a valid part of the user address space, the namelen argument is too small, the buffer length for lpCalleeData, lpSQOS, and lpGQOS are too small, or the buffer length for lpCallerData is too large.
WSAEINVAL | The parameter s is a listening socket, or the destination address specified is not consistent with that of the constrained group the socket belongs to.
WSAEISCONN | The socket is already connected (connection-oriented sockets only).
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAENOBUFS | No buffer space is available. The socket cannot be connected.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The flow specifications specified in lpSQOS and lpGQOS cannot be satisfied.
WSAEPROTONOSUPPORT | The lpCallerData augment is not supported by the service provider.
WSAETIMEDOUT | Attempt to connect timed out without establishing a connection.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the connection cannot be completed immediately. It is possible to WSPSelect the socket while it is connecting by WSPSelecting it for writing.
WSAEACCES | Attempt to connect datagram socket to broadcast address failed because WSPSetSockOpt SO_BROADCAST is not enabled.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPAccept, WSPBind, WSPGetSockName, WSPGetSockOpt, WSPSocket, WSPSelect, WSPEventSelect, WSPEnumNetworkEvents


WSPDuplicateSocket

The WSPDuplicateSocket function returns a WSAPROTOCOL_INFOW structure that can be used to create a new socket descriptor for a shared socket.

int WSPDuplicateSocket (
  SOCKET s,
  DWORD dwProcessId,
  LPWSAPROTOCOL_INFOW lpProtocolInfo,
  LPINT lpErrno
);

Parameters

s
[in] Specifies the local socket descriptor.
dwProcessId
[in] Specifies the ID of the target process for which the shared socket will be used.
lpProtocolInfo
[out] A pointer to a buffer allocated by the client that is large enough to contain a WSAPROTOCOL_INFOW structure. The service provider copies the protocol info structure contents to this buffer.
lpErrno
[out] A pointer to the error code.

Remarks

A source process calls WSPDuplicateSocket to obtain a special WSAPROTOCOL_INFOW structure. It uses some interprocess communications (IPC) mechanism to pass the contents of this structure to a target process, which in turn uses it in a call to WSPSocket to obtain a descriptor for the duplicated socket. Note that the special WSAPROTOCOL_INFOW structure can only be used once by the target process.

It is the service provider's responsibility to perform whatever operations are needed in the source process context and to create a WSAPROTOCOL_INFOW structure that will be recognized when it subsequently appears as a parameter to WSPSocket in the target processes' context. The provider must then return a socket descriptor that references a common underlying socket. The dwProviderReserved field of the WSAPROTOCOL_INFOW structure is available for the service provider's use, and can be used to store any useful context information, including a duplicated handle.

As is described in section 3.4.1. Descriptor Allocation, when new socket descriptors are allocated IFS providers must call WPUModifyIFSHandle and non-IFS providers must call WPUCreateSocketHandle.

One possible scenario for establishing and using a shared socket in a handoff mode is illustrated below:

Source Process | IPC | Destination Process
1) WSPSocket, WSPConnect |  |
2) Request target process ID | Þ |
 |  | 3) Receive process ID request and respond
4) Receive process ID | Ü |
5) Call WSPDuplicateSocket to get a special WSAPROTOCOL_INFOW structure |  |
6) Send WSAPROTOCOL_INFOW structure to target |  |
 | Þ | 7) Receive WSAPROTOCOL_INFOW structure
 |  | 8) Call WSPSocket to create shared socket descriptor.
10) WSPClosesocket |  | 9) Use shared socket for data exchange

Return Values

If no error occurs, WSPDuplicateSocket returns zero. Otherwise, the value of SOCKET_ERROR is returned, and a specific error number is available in lpErrno.

Comments

The descriptors that reference a shared socket can be used independently as far as I/O is concerned. However, the Windows Sockets interface does not implement any type of access control, so it is up to the processes involved to coordinate their operations on a shared socket. A typical use for shared sockets is to have one process that is responsible for creating sockets and establishing connections, hand off sockets to other processes which are responsible for information exchange.

Since what is duplicated are the socket descriptors and not the underlying socket, all of the state associated with a socket is held in common across all the descriptors. For example a WSPSetSockOpt operation performed using one descriptor is subsequently visible using a WSPGetSockOpt from any or all descriptors. A process can call WSPClosesocket on a duplicated socket and the descriptor will become deallocated. The underlying socket, however, will remain open until WSPClosesocket is called by the last remaining descriptor.

Notification on shared sockets is subject to the usual constraints of WSPAsyncSelect and WSPEventSelect. Issuing either of these calls using any of the shared descriptors cancels any previous event registration for the socket, regardless of which descriptor was used to make that registration. Thus, for example, a shared socket cannot deliver FD_READ events to process A and FD_WRITE events to process B. For situations when such tight coordination is required, it is suggested that developers use threads instead of separate processes.

A layered service provider supplies an implementation of this function, but it is also a client of this function if and when it calls WSPDuplicateSocket of the next layer in the protocol chain. Some special considerations apply to this function's lpProtocolInfo parameter as it is propagated down through the layers of the protocol chain.

If the next layer in the protocol chain is another layer then when the next layer's WSPDuplicateSocket is called, this layer must pass to the next layer a lpProtocolInfo that references the same unmodified WSAPROTOCOL_INFOW structure with the same unmodified chain information. However, if the next layer is the base protocol (i.e., the last element in the chain), this layer performs a substitution when calling the base provider's WSPDuplicateSocket. In this case, the base provider's WSAPROTOCOL_INFOW structure should be referenced by the lpProtocolInfo parameter.

One vital benefit of this policy is that base service providers do not have to be aware of protocol chains. This same propagation policy applies when propagating a WSAPROTOCOL_INFOW structure through a layered sequence of other functions such as WSPAddressToString, WSPStartup, WSPSocket, or WSPStringToAddress.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that one of the specified parameters was invalid.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAEMFILE | No more socket descriptors are available.
WSAENOBUFS | No buffer space is available. The socket cannot be created.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCreateSocketHandle, WPUModifyIFSHandle


WSPEnumNetworkEvents

The WSPEnumNetworkEvents function reports occurrences of network events for the indicated socket.

int WSPEnumNetworkEvents (
  SOCKET s,
  WSAEVENT hEventObject,
  LPWSANETWORKEVENTS lpNetworkEvents,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying the socket.
hEventObject
[in] An optional handle identifying an associated event object to be reset.
lpNetworkEvents
[out] A pointer to a WSANETWORKEVENTS structure which is filled with a record of occurred network events and any associated error codes. The WSANETWORKEVENTS structure is defined below.
lpErrno
[out] A pointer to the error code.

Remarks

This function is used to report which network events have occurred for the indicated socket since the last invocation of this function. It is intended for use in conjunction with WSPEventSelect, which associates an event object with one or more network events. Recording of network events commences when WSPEventSelect is called with a nonzero lNetworkEvents parameter and remains in effect until another call is made to WSPEventSelect with the lNetworkEvents parameter set to zero, or until a call is made to WSPAsyncSelect.

WSPEnumNetworkEvents only reports network activity and errors nominated through WSPEventSelect. See the descriptions of WSPSelect and WSPAsyncSelect to find out how those functions report network activity and errors.

The socket's internal record of network events is copied to the structure referenced by lpNetworkEvents, whereafter the internal network events record is cleared. If hEventObject is non-null, the indicated event object is also reset. The Windows Sockets provider guarantees that the operations of copying the network event record, clearing it and resetting any associated event object are atomic, such that the next occurrence of a nominated network event will cause the event object to become set. In the case of this function returning SOCKET_ERROR, the associated event object is not reset and the record of network events is not cleared.

The WSANETWORKEVENTS structure is defined as follows:

typedef struct _WSANETWORKEVENTS {
       long lNetworkEvents;
       int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;

The lNetworkEvent field of the structure indicates which of the FD_XXX network events have occurred. The iErrorCode array is used to contain any associated error codes, with array index corresponding to the position of event bits in lNetworkEvents. The identifiers such as FD_READ_BIT and FD_WRITE_BIT can be used to index the iErrorCode array.

Note that only those elements of the iErrorCode array are set that correspond to the bits set in lNetworkEvents field. Other fields are not modified (this is important for backwards compatibility with the Windows Socket 2 SPI clients that are not aware of new FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events).

The following error codes can be returned along with the respective network event:

Event: FD_CONNECT

Error Code | Meaning
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to connect was forcefully rejected.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAENOBUFS | No buffer space is available. The socket cannot be connected.
WSAETIMEDOUT | Attempt to connect timed out without establishing a connection.

Event: FD_CLOSE

Error Code | Meaning
WSAENETDOWN | The network subsystem has failed.
WSAECONNRESET | The connection was reset by the remote side.
WSAECONNABORTED | The connection was terminated due to a time-out or other failure.

Event: FD_READ

Event: FD_WRITE

Event: FD_OOB

Event: FD_ACCEPT

Event: FD_QOS

Event: FD_GROUP_QOS

Event: FD_ADDRESS_LIST_CHANGE

Event: FD_ROUTING_INTERFACE_CHANGE

Error Code | Meaning
WSAENETUNREACH | The specified destination is no longer reachable.
WSAENETDOWN | The network subsystem has failed.

Error Code | Meaning
WSAENETDOWN | The network subsystem has failed.

Return Values

The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that one of the specified parameters was invalid.
WSAEINPROGRESS | A blocking Windows Sockests call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPEventSelect


WSPEventSelect

The WSPEventSelect function specifies an event object to be associated with the supplied set of network events.

int WSPEventSelect (
  SOCKET s,
  WSAEVENT hEventObject,
  long lNetworkEvents,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying the socket.
hEventObject
[in] A handle identifying the event object to be associated with the supplied set of network events.
lNetworkEvents
[in] A bitmask which specifies the combination of network events in which the Windows Sockets SPI client has interest.
lpErrno
[out] A pointer to the error code.

Remarks

This function is used to specify an event object, hEventObject, to be associated with the selected network events, lNetworkEvents. The socket for which an event object is specified is identified by s. The event object is set when any of the nominated network events occur.

WSPEventSelect operates very similarly to WSPAsyncSelect, the difference being in the actions taken when a nominated network event occurs. Whereas WSPAsyncSelect causes a Windows Sockets SPI client-specified Windows message to be posted, WSPEventSelect sets the associated event object and records the occurrence of this event in an internal network event record. A Windows Sockets SPI client can use WSPEnumNetworkEvents to retrieve the contents of the internal network event record and thus determine which of the nominated network events have occurred.

WSPEventSelect is the only function that causes network activity and errors to be recorded and retrievable through WSPEnumNetworkEvents. See the descriptions of WSPSelect and WSPAsyncSelect to find out how those functions report network activity and errors.

This function automatically sets socket s to nonblocking mode, regardless of the value of lNetworkEvents.

The lNetworkEvents parameter is constructed by OR'ing any of the values specified in the following list.

Value | Meaning
FD_READ | Issue notification of readiness for reading
FD_WRITE | Issue notification of readiness for writing
FD_OOB | Issue notification of the arrival of out-of-band data
FD_ACCEPT | Issue notification of incoming connections
FD_CONNECT | Issue notification of completed connection
FD_CLOSE | Issue notification of socket closure
FD_QOS | Issue notification of socket Quality of Service (QOS) changes
FD_GROUP_QOS | Reserved for future use with socket groups: Issue notification of socket group Quality of Service (QOS) changes
FD_ROUTING _INTERFACE_CHANGE | Issue notification of routing interface changes for the specified destination(s)
FD_ADDRESS_LIST _CHANGE | Issue notification of local address list changes for the socket's address family

Issuing a WSPEventSelect for a socket cancels any previous WSPAsyncSelect or WSPEventSelect for the same socket and clears the internal network event record. For example, to associate an event object with both reading and writing network events, the Windows Sockets SPI client must call WSPEventSelect with both FD_READ and FD_WRITE, as follows:

rc = WSPEventSelect(s, hEventObject, FD_READ|FD_WRITE);\

It is not possible to specify different event objects for different network events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE network event will be associated with hEventObject2:

rc = WSPEventSelect(s, hEventObject1, FD_READ);
rc = WSPEventSelect(s, hEventObject2, FD_WRITE);   //bad

To cancel the association and selection of network events on a socket, lNetworkEvents should be set to zero, in which case the hEventObject parameter will be ignored.

rc = WSPEventSelect(s, hEventObject, 0);

Closing a socket with WSPCloseSocket also cancels the association and selection of network events specified in WSPEventSelect for the socket. The Windows Sockets SPI client, however, still must call WSACloseEvent to explicitly close the event object and free any resources.

Since an accepted (WSPAccept ) socket has the same properties as the listening socket used to accept it, any WSPEventSelect association and network events selection set for the listening socket apply to the accepted socket. For example, if a listening socket has WSPEventSelect association of hEventOject with FD_ACCEPT, FD_READ, and FD_WRITE, then any socket accepted on that listening socket will also have FD_ACCEPT, FD_READ, and FD_WRITE network events associated with the same hEventObject. If a different hEventObject or network events are needed, the Windows Sockets SPI client should call WSPEventSelect, passing the accepted socket and the new information.

Return Values

The return value is zero if the Windows Sockets SPI client's specification of the network events and the associated event object was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number is available in lpErrno.

Comments

Having successfully recorded the occurrence of the network event and signaled the associated event object, no further actions are taken for that network event until the Windows Sockets SPI client makes the function call which implicitly re-enables the setting of that network event and signaling of the associated event object.

Network Event | Re-enabling function
FD_READ | WSPRecv or WSPRecvFrom
FD_WRITE | WSPSend or WSPSendTo
FD_OOB | WSPRecv or WSPRecvFrom
FD_ACCEPT | WSPAccept unless the error code returned is WSATRY_AGAIN indicating that the condition function returned CF_DEFER
FD_CONNECT | NONE
FD_CLOSE | NONE
FD_QOS | WSPIoctl with SIO_QOS
FD_GROUP_QOS | Reserved for future use with socket groups: WSPIoctl with SIO_GROUP_QOS
FD_ROUTING _INTERFACE_CHANGE | WSPIoctl with command SIO_ROUTING_INTERFACE_CHANGE
FD_ADDRESS_LIST _CHANGE | WSPIoctl with command SIO_ADDRESS_LIST_CHANGE

Any call to the re-enabling routine, even one which fails, results in re-enabling of recording and signaling for the relevant network event and event object, respectively.

For FD_READ, FD_OOB, and FD_ACCEPT network events, network event recording and event object signaling are "level-triggered." This means that if the re-enabling routine is called and the relevant network condition is still valid after the call, the network event is recorded and the associated event object is signaled. This allows a Windows Sockets SPI client to be event-driven and not be concerned with the amount of data that arrives at any one time. Consider the following sequence:

  1. Service provider receives 100 bytes of data on socket s, records the FD_READ network event and signals the associated event object.
  2. The Windows Sockets SPI client issues WSPRecv( s, buffptr, 50, 0) to read 50 bytes.
  3. The service provider records the FD_READ network event and signals the associated event object again since there is still data to be read.

With these semantics, a Windows Sockets SPI client need not read all available data in response to an FD_READ network event—a single WSPRecv in response to each FD_READ network event is appropriate.

The FD_QOS and FD_GROUP_QOS events are considered edge triggered. A message will be posted exactly once when a QOS change occurs. Further indications will not be issued until either the service provider detects a further change in QOS or the Windows Sockets SPI client renegotiates the QOS for the socket.

The FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events are considered "edge triggered" as well. A message will be posted exactly once when a change occurs AFTER the Windows Socket SPI client has request the notification by issuing WSAIoctl with SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE correspondingly.. Further messages will not be forthcoming until the SPI client reissues the IOCTL AND another change is detected since the IOCTL has been issued.

If a network event has already happened when the Windows Sockets SPI client calls WSPEventSelect or when the re-enabling function is called, then a network event is recorded and the associated event object is signaled as appropriate. For example, consider the following sequence:

  1. A Windows Sockets SPI client calls WSPListen
  2. A connect request is received but not yet accepted
  3. The Windows Sockets SPI client calls WSPEventSelect specifying that it is interested in the FD_ACCEPT network event for the socket. The service provider records the FD_ACCEPT network event and signals the associated event object immediately.

The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded when a socket is first connected with WSPConnect or accepted with WSPAccept, and then after a WSPSend or WSPSendTo fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, a Windows Sockets SPI client can assume that sends are possible starting from the first FD_WRITE network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the Windows Sockets SPI client will find out that sends are again possible when an FD_WRITE network event is recorded and the associated event object is signaled.

The FD_OOB network event is used only when a socket is configured to receive out-of-band data separately. If the socket is configured to receive out-of-band data in-line, the out-of-band (expedited) data is treated as normal data and the Windows Sockets SPI client should register an interest in, and will get, FD_READ network event, not FD_OOB network event. A Windows Sockets SPI client can set or inspect the way in which out-of-band data is to be handled by using WSPSetSockOpt or WSPGetSockOpt for the SO_OOBINLINE option.

The error code in an FD_CLOSE network event indicates whether the socket close was graceful or abortive. If the error code is zero, then the close was graceful; if the error code is WSAECONNRESET, then the socket's virtual circuit was reset. This only applies to connection-oriented sockets such as SOCK_STREAM.

The FD_CLOSE network event is recorded when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means that the FD_CLOSE is recorded when the connection goes into the FIN WAIT or CLOSE WAIT states. This results from the remote end performing a WSPShutdown on the send side or a WSPCloseSocket.

Service providers shall record ONLY an FD_CLOSE network event to indicate closure of a virtual circuit, they shall not record an FD_READ network event to indicate this condition.

The FD_QOS or FD_GROUP_QOS network event is recorded when any field in the flow specification associated with socket s or the socket group that s belongs to has changed, respectively. This change must be made available to Windows Sockets SPI clients through the WSPIoctl function with SIO_GET_QOS and/or SIO_GET_GROUP_QOS to retrieve the current QOS for socket s or for the socket group s belongs to, respectively.

The FD_ROUTING_INTERFACE_CHANGE nework event is recorded when the local interface that should be used to reach the destination specified in WSAIoctl with SIO_ROUTING_INTERFACE_CHANGE changes AFTER such IOCTL has been issued.

The FD_ADDRESS_LIST_CHANGE network event is recorded when the list of addresses of socket's protocol family to which the Windows Socket SPI client can bind changes after WSAIoctl with SIO_ADDRESS_LIST_CHANGE has been issued.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | Indicates that one of the specified parameters was invalid, or the specified socket is in an invalid state.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPEnumNetworkEvents


WSPGetOverlappedResult

The WSPGetOverlappedResult function returns the results of an overlapped operation on the specified socket.

BOOL WSPGetOverlappedResult (
  SOCKET s,
  LPWSAOVERLAPPED lpOverlapped,
  LPDWORD lpcbTransfer,
  BOOL fWait,
  LPDWORD lpdwFlags,
  LPINT lpErrno
);

Parameters

s
[in] Identifies the socket. This is the same socket that was specified when the overlapped operation was started by a call to WSPRecv, WSPRecvFrom, WSPSend, WSPSendTo, or WSPIoctl.
lpOverlapped
[in] Points to a WSAOVERLAPPED structure that was specified when the overlapped operation was started.
lpcbTransfer
[out] Points to a 32-bit variable that receives the number of bytes that were actually transferred by a send or receive operation, or by WSPIoctl.
fWait
[in] Specifies whether the function should wait for the pending overlapped operation to complete. If TRUE, the function does not return until the operation has been completed. If FALSE and the operation is still pending, the function returns FALSE and lpErrno is WSA_IO_INCOMPLETE. The fWait parameter may be set to TRUE only if the overlapped operation selected event-based completion notification.
lpdwFlags
[out] Points to a 32-bit variable that will receive one or more flags that supplement the completion status. If the overlapped operation was initiated through WSPRecv or WSPRecvFrom, this parameter will contain the results value for lpFlags parameter.
lpErrno
[out] A pointer to the error code.

Remarks

The results reported by the WSPGetOverlappedResult function are those of the specified socket's last overlapped operation to which the specified WSAOVERLAPPED structure was provided, and for which the operation's results were pending. A pending operation is indicated when the function that started the operation returns SOCKET_ERROR, and the lpErrno is WSA_IO_PENDING. When an I/O operation is pending, the function that started the operation resets the hEvent member of the WSAOVERLAPPED structure to the nonsignaled state. Then when the pending operation has been completed, the system sets the event object to the signaled state.

If the fWait parameter is TRUE, WSPGetOverlappedResult determines whether the pending operation has been completed by blocking and waiting for the event object to be in the signaled state. A client may set fWait parameter to TRUE only if it selected event-based completion notification when the IO operation was requested. If another form of notification was selected, the usage of the hEvent member of the WSAOVERLAPPED structure is different, and setting fWait to TRUE causes unpredictable results.

Interaction with WPUCompleteOverlappedRequest

The behavior of WPUCompleteOverlappedRequest places some constraints on how a service provider implements WSPGetOverlappedResult since only the Offset and OffsetHigh members of the WSAOVERLAPPED structure are exclusively controlled by the service provider even though three values (byte count, flags, and error) must be retrieved from the structure by WSPGetOverlappedResult. A service provider may accomplish this any way it chooses as long as it interacts with the behavior of WPUCompleteOverlappedRequest properly. The following description present s a typical typical implementation:

At the start of overlapped processing, the service provider sets Internal to WSS_OPERATION_IN_PROGRESS.

When the IO operation is complete, the provider sets OffsetHigh to the Windows Sockets 2 error code resulting from the operation, sets Offset to the flags resulting from the IO operation, and calls WPUCompleteOverlappedRequest, passing the transfer byte count as one of the parameters. WPUCompleteOverlappedRequest eventually sets InternalHigh to the transfer byte count, then sets Internal to a value other than WSS_OPERATION_IN_PROGRESS.

When WSPGetOverlappedResult is called, the service provider checks Internal. If it is WSS_OPERATION_IN_PROGRESS, the provider waits on the event handle in the hEvent member or returns an error, based on the setting of the fWait flag of WSPGetOverlappedResult. If not in progress, or after completion of waiting, the provider returns the values from InternalHigh, OffsetHigh, and Offset as the transfer count, operation result error code, and flags respectively.

Return Values

If WSPGetOverlappedResult succeeds, the return value is TRUE. This means that the overlapped operation has completed successfully and that the value pointed to by lpcbTransfer has been updated. If WSPGetOverlappedResult returns FALSE, this means that either the overlapped operation has not completed or the overlapped operation completed but with errors, or that completion status could not be determined due to errors in one or more parameters to WSPGetOverlappedResult. On failure, the value pointed to by lpcbTransfer will not be updated. lpErrno indicates the cause of the failure (either of WSPGetOverlappedResult or of the associated overlapped operation).

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSA_INVALID_HANDLE | The hEvent field of the WSAOVERLAPPED structure does not contain a valid event object handle.
WSA_EINVAL | One of the parameters is unacceptable.
WSA_IO_INCOMPLETE | fWait is FALSE and the I/O operation has not yet completed.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPRecv, WSPRecvFrom, WSPSend, WSPSendTo, WSPConnect, WSPAccept, WSPIoctl, WPUCompleteOverlappedRequest


WSPGetPeerName

The WSPGetPeerName function gets the address of the peer to which a socket is connected.

int WSPGetPeerName (
  SOCKET s,
  struct sockaddr FAR * name,
  LPINT namelen,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a connected socket.
name
[out] A pointer to the structure which is to receive the name of the peer.
namelen
[in/out] A pointer to an integer which, on input, indicates the size of the structure pointed to by name, and on output indicates the size of the returned name.
lpErrno
[out] A pointer to the error code.

Remarks

WSPGetPeerName supplies the name of the peer connected to the socket s and stores it in the struct SOCKADDR referenced by name. It can be used only on a connected socket. For datagram sockets, only the name of a peer specified in a previous WSPConnect call will be returned—any name specified by a previous WSPSendTo call will not be returned by WSPGetPeerName.

On return, the namelen argument contains the actual size of the name returned in bytes.

Return Values

If no error occurs, WSPGetPeerName returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The name or the namelen argument is not a valid part of the user address space, or the namelen argument is too small.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAENOTCONN | The socket is not connected.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPBind, WSPSocket, WSPGetSockName


WSPGetQOSByName

The WSPGetQOSByName function initializes a QOS structure based on a named template, or retrieves an enumeration of the available template names.

BOOL WSPGetQOSByName (
  SOCKET s,
  LPWSABUF lpQOSName,
  LPQOS lpQOS,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
lpQOSName
[in out] Specifies the QOS template name, or supplies a buffer to retrieve an enumeration of the available template names.
lpQOS
[out] A pointer to the QOS structure to be filled.
lpErrno
[out] A pointer to the error code.

Remarks

Clients can use WSPGetQOSByName to initialize a QOS structure to a set of known values appropriate for a particular service class or media type. These values are stored in a template which is referenced by a well-known name. The client may retrieve these values by setting the buf member of the WSABUF indicated by lpQOSName to point to a Unicode string of non-zero length specifying a template name. In this case the usage of lpQOSName is IN only, and results are returned through lpQOS.

Alternatively, the client may use WSPGetQOSByName to retrieve an enumeration of available template names. The client may do this by setting the buf member of the WSABUF indicated by lpQOSName to a zero-length null-terminated Unicode string. In this case the buffer indicated by buf is over-written with a sequence of as many null-terminated Unicode template name strings are available up to the number of bytes available in buf as indicated by the len member of the WSABUF indicated by lpQOSName. The list of names itself is terminated by a zero-length Unicode name string. When WSPGetQOSByName is used to retrieve template names, the lpQOS parameter is ignored.

Return Values

If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpQOS argument is not a valid part of the user address space, or the buffer length for lpQOS is too small.
WSAEINVAL | The specified QOS template name is invalid.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPConnect, WSPAccept, WSPGetSockOpt


WSPGetSockName

The WSPGetSockName function gets the local name for a socket.

int WSPGetSockName (
  SOCKET s,
  struct sockaddr FAR * name,
  LPINT namelen,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a bound socket.
name
[out] A pointer to a structure used to supply the address (name) of the socket.
namelen
[in/out] A pointer to an integer which, on input, indicates the size of the structure pointed to by name, and on output indicates the size of the returned name.
lpErrno
[out] A pointer to the error code.

Remarks

WSPGetSockName retrieves the current name for the specified socket descriptor in name. It is used on a bound and/or connected socket specified by the s parameter. The local association is returned. This call is especially useful when a WSPConnect call has been made without doing a WSPBind first; as this call provides the only means by which the local association that has been set by the service provider can be determined.

If a socket was bound to an unspecified address (for example, ADDR_ANY), indicating that any of the host's addresses within the specified address family should be used for the socket, WSPGetSockName will not necessarily return information about the host address, unless the socket has been connected with WSPConnect or WSPAccept. The Windows Sockets SPI client must not assume that an address will be specified unless the socket is connected. This is because for a multihomed host the address that will be used for the socket is unknown until the socket is connected.

Return Values

If no error occurs, WSPGetSockName returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The name or the namelen argument is not a valid part of the user address space, or the namelen argument is too small.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAENOTSOCK | The descriptor is not a socket.
WSAEINVAL | The socket has not been bound to an address with WSPBind, or ADDR_ANY is specified in WSPBind but connection has not yet occurs.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPBind, WSPSocket, WSPGetPeerName


WSPGetSockOpt

The WSPGetSockOpt function retrieves a socket option.

int WSPGetSockOpt (
  SOCKET s,
  int level,
  int optname,
  char FAR * optval,
  LPINT optlen,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
level
[in] The level at which the option is defined; the supported levels include SOL_SOCKET (See annex for more protocol-specific levels.)
optname
[in] The socket option for which the value is to be retrieved.
optval
[out] A pointer to the buffer in which the value for the requested option is to be returned.
optlen
[in/out] A pointer to the size of the optval buffer.
lpErrno
[out] A pointer to the error code.

Remarks

WSPGetSockOpt retrieves the current value for a socket option associated with a socket of any type, in any state, and stores the result in optval. Options can exist at multiple protocol levels, but they are always present at the uppermost "socket'' level. Options affect socket operations, such as the routing of packets and out-of-band data transfer.

The value associated with the selected option is returned in the buffer optval. The integer pointed to by optlen should originally contain the size of this buffer; on return, it will be set to the size of the value returned. For SO_LINGER, this will be the size of a structure linger; for most other options it will be the size of an integer.

The Windows Sockets SPI client is responsible for allocating any memory space pointed to directly or indirectly by any of the parameters it specifies.

If the option was never set with WSPSetSockOpt, then WSPGetSockOpt returns the default value for the option.

level = SOL_SOCKET

Value | Type | Meaning | Default
SO_ACCEPTCONN | BOOL | Socket is WSPListening. | FALSE unless a WSPListen has been performed
SO_BROADCAST | BOOL | Socket is configured for the transmission of broadcast messages. | FALSE
SO_DEBUG | BOOL | Debugging is enabled. | FALSE
SO_DONTLINGER | BOOL | If true, the SO_LINGER option is disabled. | TRUE
SO_DONTROUTE | BOOL | Routing is disabled. | FALSE
SO_ERROR | int | Retrieve error status and clear. | 0
SO_GROUP_ID | GROUP | Reserved for future use with socket groups: The identifier of the group to which this socket belongs. | NULL
SO_GROUP_PRIORITY | int | Reserved for future use with socket groups: The relative priority for sockets that are part of a socket group. | 0
SO_KEEPALIVE | BOOL | Keepalives are being sent. | FALSE
SO_LINGER | struct linger | Returns the current linger options. | 1 is on (default), 0 is off
SO_MAX_MSG_SIZE | unsigned int | Maximum size of a message for message-oriented socket types (for example, SOCK_DGRAM). Has no meaning for stream oriented sockets. | Implementation dependent
SO_OOBINLINE | BOOL | Out-of-band data is being received in the normal data stream. | FALSE
SO_PROTOCOL_INFO | WSA PROTOCOL _INFO | Description of protocol info for protocol that is bound to this socket. | protocol dependent
SO_RCVBUF | int | Total per-socket buffer space reserved for receives. This is unrelated to SO_MAX_MSG_SIZE or the size of a TCP window. | Implementation dependent
SO_REUSEADDR | BOOL | The socket can be bound to an address which is already in use. | FALSE
SO_SNDBUF | int | Total per-socket buffer space reserved for sends. This is unrelated to SO_MAX_MSG_SIZE or the size of a TCP window. | Implementation dependent
SO_TYPE | int | The type of the socket (for example, SOCK_STREAM). | As created with socket.
PVD_CONFIG | Service Provider Dependent | An "opaque" data structure object from the service provider associated with socket s. This object stores the current configuration information of the service provider. The exact format of this data structure is service provider specific. | Implementation dependent

Calling WSPGetSockOpt with an unsupported option will result in an error code of WSAENOPROTOOPT being returned in lpErrno.

SO_DEBUG
Windows Sockets service providers are encouraged (but not required) to supply output debug information if the SO_DEBUG option is set by a Windows Sockets SPI client. The mechanism for generating the debug information and the form it takes are beyond the scope of this specification.
SO_ERROR
The SO_ERROR option returns and resets the per-socket based error code (which is not necessarily the same as the per-thread error code that is maintained by the WS2_32.DLL). A successful Windows Sockets call on the socket does not reset the socket-based error code returned by the SO_ERROR option.
SO_GROUP_ID
Reserved for future use with socket groups: This is a get-only socket option which supplies the identifier of the group this socket belongs to. Note that socket group IDs are unique across all processes for a give service provider. If this socket is not a group socket, the value is NULL.
SO_GROUP_PRIORITY
Reserved for future use with socket groups: Group priority indicates the priority of the specified socket relative to other sockets within the socket group. Values are non-negative integers, with zero corresponding to the highest priority. Priority values represent a hint to the service provider about how potentially scarce resources should be allocated. For example, whenever two or more sockets are both ready to transmit data, the highest priority socket (lowest value for SO_GROUP_PRIORITY) should be serviced first, with the remainder serviced in turn according to their relative priorities.

The WSAENOPROTOOPT error code is indicated for non group sockets or for service providers which do not support group sockets.

SO_KEEPALIVE
A Windows Sockets SPI client can request that a TCP/IP service provider enable the use of "keep-alive" packets on TCP connections by turning on the SO_KEEPALIVE socket option. A Windows Sockets provider need not support the use of keep-alives: if it does, the precise semantics are implementation-specific but should conform to section 4.2.3.6 of RFC 1122: Requirements for Internet Hosts — Communication Layers. If a connection is dropped as the result of "keep-alives" the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN.
SO_LINGER
SO_LINGER controls the action taken when unsent data is queued on a socket and a WSPCloseSocket is performed. See WSPCloseSocket for a description of the way in which the SO_LINGER settings affect the semantics of WSPCloseSocket. The Windows Sockets SPI client obtains the desired behavior by creating a struct linger (pointed to by the optval argument) with the following elements:
struct linger {
    u_short    l_onoff;
    u_short    l_linger;
}
SO_MAX_MSG_SIZE
This is a get-only socket option which indicates the maximum size of an outbound send message for message-oriented socket types (for example, SOCK_DGRAM) as implemented by the service provider. It has no meaning for byte stream oriented sockets. There is no provision to determine the maximum inbound message size.
SO_PROTOCOL_INFOW
This is a get-only option which supplies the WSAPROTOCOL_INFO structure associated with this socket. See WSCEnumProtocols for more information about this structure.
SO_SNDBUF
When a Windows Sockets service provider supports the SO_RCVBUF and SO_SNDBUF options, a Windows Sockets SPI client can use WSPSetSockOpt to request different buffer sizes (larger or smaller). The call can succeed even though the service provider did not make available the entire amount requested. A Windows Sockets SPI client must call this function with the same option to check the buffer size actually provided.
SO_REUSEADDR
By default, a socket can not be bound (see WSPBind) to a local address which is already in use. On occasion, however, it may be desirable to "re-use" an address in this way. Since every connection is uniquely identified by the combination of local and remote addresses, there is no problem with having two sockets bound to the same local address as long as the remote addresses are different. To inform the Windows Sockets provider that a WSPBind on a socket should be allowed to bind to a local address that is already in use by another socket, the Windows Sockets SPI client should set the SO_REUSEADDR socket option for the socket before issuing the WSPBind. Note that the option is interpreted only at the time of the WSPBind: it is therefore unnecessary (but harmless) to set the option on a socket which is not to be bound to an existing address, and setting or resetting the option after the WSPBind has no effect on this or any other socket.
PVD_CONFIG
This option retrieves an "opaque" data structure object from the service provider associated with socket s. This object stores the current configuration information of the service provider. The exact format of this data structure is service provider specific.

Return Values

If no error occurs, WSPGetSockOpt returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | One of the optval or the optlen arguments is not a valid part of the user address space, or the optlen argument is too small.
WSAEINVAL | level is unknown or invalid.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAENOPROTOOPT | The option is unknown or unsupported by the indicated protocol family.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPSetSockOpt, WSPSocket


WSPIoctl

The WSPIoctl function controls the mode of a socket.

int WSPIoctl (
  SOCKET s,
  DWORD dwIoControlCode,
  LPVOID lpvInBuffer,
  DWORD cbInBuffer,
  LPVOID lpvOutBuffer,
  DWORD cbOutBuffer,
  LPDWORD lpcbBytesReturned,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  LPWSATHREADID lpThreadId,
  LPINT lpErrno
);

Parameters

s
[in] Handle to a socket
dwIoControlCode
[in] Control code of operation to perform
lpvInBuffer
[in] Address of input buffer
cbInBuffer
[in] Size of input buffer
lpvOutBuffer
[out] Address of output buffer
cbOutBuffer
[in] Size of output buffer
lpcbBytesReturned
[out] A pointer to the size of output buffer's contents.
lpOverlapped
[in] Address of WSAOVERLAPPED structure (ignored for non-overlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the operation has been completed (ignored for non-overlapped sockets).
lpThreadId
[in] A pointer to a WSATHREADID structure to be used by the provider in a subsequent call to WPUQueueApc. The provider should store the referenced WSATHREADID structure (not the pointer to same) unitl after the WPUQueueApc function returns.
lpErrno
[out] A pointer to the error code.

Remarks

This routine is used to set or retrieve operating parameters associated with the socket, the transport protocol, or the communications subsystem. If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a non-overlapped socket.

For nonoverlapped sockets, lpOverlapped and lpCompletionRoutine parameters are ignored, and this function can block if socket s is in the blocking mode. Note that if socket s is in the nonblocking mode, this function can return WSAEWOULDBLOCK if the specified operation cannot be finished immediately. In this case, the Windows Sockets SPI client may change the socket to the blocking mode and reissue the request request or wait for the corresponding network event (such as FD_ROUTING_INTERFACE_CHANGE or FD_ADDRESS_LIST_CHANGE in case of SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE) using Windows message (via WSPAsyncSelect or event (using WSPEventSelect) based notification mechanism.. For overlapped sockets, operations that cannot be completed immediately will be initiated, and completion will be indicated at a later time. The final completion status is retrieved through the WSPGetOverlappedResult.

Any ioctl may block indefinitely, depending on the implementation of the service provider. If the Windows Sockets SPI client cannot tolerate blocking in a WSPIoctl call, overlapped I/O would be advised for ioctls that are especially likely to block including:

SIO_FINDROUTE

SIO_FLUSH

SIO_GET_QOS

SIO_GET_GROUP_QOS

SIO_SET_QOS

SIO_SET_GROUP_QOS

SIO_ROUTING_INTERFACE_CHANGE

SIO_ADDRESS_LIST_CHANGE

Some protocol-specific ioctls may also be especially likely to block. Check the relevant protocol-specific annex for any available information.

In as much as the dwIoControlCode parameter is now a 32-bit entity, it is possible to adopt an encoding scheme that provides a convenient way to partition the opcode identifier space. The dwIoControlCode parameter is architected to allow for protocol and vendor independence when adding new control codes, while retaining backward compatibility with Windows Sockets 1.1 and Unix control codes. The dwIoControlCode parameter has the following form:

3 | 3 | 2 | 2 2 | 2 2 2 2 2 2 2 1 1 1 1 | 1 1 1 1 1 1
1 | 0 | 9 | 8 7 | 6 5 4 3 2 1 0 9 8 7 6 | 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
I | O | V | T | Vendor/Address Family | Code

I is set if the input buffer is valid for the code, as with IOC_IN.

O is set if the output buffer is valid for the code, as with IOC_OUT. Note that for codes with both input and output parameters, both I and O will be set.

V is set if there are no parameters for the code, as with IOC_VOID.

T is a two-bit quantity which defines the type of ioctl. The following values are defined:

0 – The ioctl is a standard Unix ioctl code, as with FIONREAD and FIONBIO.

1 – The ioctl is a generic Windows Sockets 2 ioctl code. New ioctl codes defined for Windows Sockets 2 will have T == 1.

2 – The ioctl applies only to a specific address family.

3 – The ioctl applies only to a specific vendor's provider. This type allows companies to be assigned a vendor number which appears in the Vendor/AddressFamily field. Then, the vendor can define new ioctls specific to that vendor without having to register the ioctl with a clearinghouse, thereby providing vendor flexibility and privacy.

Vendor/Address Family - An 11-bit quantity which defines the vendor who owns the code (if T == 3) or which contains the address family to which the code applies (if T == 2). If this is a Unix ioctl code (T == 0) then this field has the same value as the code on Unix. If this is a generic Windows Sockets 2 ioctl (T == 1) then this field can be used as an extension of the "code" field to provide additional code values.

Code – The specific ioctl code for the operation.

The following Unix commands are supported:

Parameters

FIONBIO
Enable or disable nonblocking mode on socket s. lpvInBuffer points at an unsigned long, which is nonzero if nonblocking mode is to be enabled and zero if it is to be disabled. When a socket is created, it operates in blocking mode (that is, nonblocking mode is disabled). This is consistent with BSD sockets.

The WSPAsyncSelect or WSPEventSelect routine automatically sets a socket to nonblocking mode. If WSPAsyncSelect or WSPEventSelect has been issued on a socket, then any attempt to use WSPIoctl to set the socket back to blocking mode will fail with WSAEINVAL. To set the socket back to blocking mode, a Windows Sockets SPI client must first disable WSPAsyncSelect by calling WSPAsyncSelect with the lEvent parameter equal to zero, or disable WSPEventSelect by calling WSPEventSelect with the lNetworkEvents parameter equal to zero.

FIONREAD
Determine the amount of data which can be read atomically from socket s. lpvOutBuffer points at an unsigned long in which WSPIoctl stores the result. If s is stream oriented (for example, type SOCK_STREAM), FIONREAD returns the total amount of data which can be read in a single receive operation; this is normally the same as the total amount of data queued on the socket. If s is message oriented (for example, type SOCK_DGRAM), FIONREAD returns the size of the first datagram (message) queued on the socket.
SIOCATMARK
Determine whether or not all out-of-band data has been read. This applies only to a socket of stream-style (for example, type SOCK_STREAM) which has been configured for in-line reception of any out-of-band data (SO_OOBINLINE). If no out-of-band data is waiting to be read, the operation returns TRUE. Otherwise, it returns FALSE, and the next receive operation performed on the socket will retrieve some or all of the data preceding the "mark"; the Windows Sockets SPI client should use the SIOCATMARK operation to determine whether any remains. If there is any normal data preceding the "urgent" (out of band) data, it will be received in order. (Note that receive operations will never mix out-of-band and normal data in the same call.) lpvOutBuffer points at a BOOL in which WSPIoctl stores the result.

The following Windows Sockets 2 commands are supported:

Parameters

SIO_ASSOCIATE_HANDLE (opcode setting: I, T==1)
Associate this socket with the specified handle of a companion interface. The input buffer contains the integer value corresponding to the manifest constant for the companion interface (for example, TH_NETDEV and TH_TAPI), followed by a value which is a handle of the specified companion interface, along with any other required information. Refer to the appropriate section in the Windows Sockets 2 Protocol-Specific Annex and/or documentation for the particular companion interface for additional details. The total size is reflected in the input buffer length. No output buffer is required. The WSAENOPROTOOPT error code is indicated for service providers which do not support this ioctl. The handle associated by this ioctl can be retrieved using SIO_TRANSLATE_HANDLE.

A companion interface might be used, for example, if a particular provider provides (1) a great deal of additional controls over the behavior of a socket and (2) the controls are provider-specific enough that they do not map to existing Windows Socket functions or ones likely to be defined in the future. It is recommend that the Component Object Model (COM) be used instead of this ioctl to discover and track other interfaces that might be supported by a socket. This ioctl is present for (reverse) compatibility with systems where COM is not available or cannot be used for some other reason.

SIO_ENABLE_CIRCULAR_QUEUEING (opcode setting: V, T==1)
Indicates to a message-oriented service provider that a newly arrived message should never be dropped because of a buffer queue overflow. Instead, the oldest message in the queue should be eliminated in order to accommodate the newly arrived message. No input and output buffers are required. Note that this ioctl is only valid for sockets associated with unreliable, message-oriented protocols. The WSAENOPROTOOPT error code is indicated for service providers which do not support this ioctl.
SIO_FIND_ROUTE (opcode setting: O, T==1)
When issued, this ioctl requests that the route to the remote address specified as a SOCKADDR in the input buffer be discovered. If the address already exists in the local cache, its entry is invalidated. In the case of Novell's IPX, this call initiates an IPX GetLocalTarget (GLT), which queries the network for the given remote address.
SIO_FLUSH (opcode setting: V, T==1)
Discards current contents of the sending queue associated with this socket. No input and output buffers are required. The WSAENOPROTOOPT error code is indicated for service providers which do not support this ioctl.
SIO_GET_BROADCAST_ADDRESS (opcode setting: O, T==1)
This ioctl fills the output buffer with a SOCKADDR structure containing a suitable broadcast address for use with WSPSendTo.
SIO_GET_EXTENSION_FUNCTION_POINTER (opcode setting: O, I, T==1)
Retrieve a pointer to the specified extension function supported by the associated service provider. The input buffer contains a GUID whose value identifies the extension function in question. The pointer to the desired function is returned in the output buffer. Extension function identifiers are established by service provider vendors and should be included in vendor documentation that describes extension function capabilities and semantics.
SIO_GET_QOS (opcode setting: O, T==1)
Retrieve the QOS structure associated with the socket. The input buffer is optional. Some protocols (for example, RSVP) allow the input buffer to be used to qualify a QOS request. The QOS structure will be copied into the output buffer. The output buffer must be sized large enough to be able to contain the full QOS structure. The WSAENOPROTOOPT error code is indicated for service providers which do not support QOS.
SIO_GET_GROUP_QOS (opcode setting: O, T==1)
Reserved for future use with socket groups: Retrieve the QOS structure associated with the socket group to which this socket belongs. The input buffer is optional. Some protocols (for example, RSVP) allow the input buffer to be used to qualify a QOS request. The QOS structure will be copied into the output buffer. If this socket does not belong to an appropriate socket group, the SendingFlowspec and ReceivingFlowspec fields of the returned QOS structure are set to NULL. The WSAENOPROTOOPT error code is indicated for service providers which do not support QOS.
SIO_MULTIPOINT_LOOPBACK (opcode setting: I, T==1)
Controls whether data sent in a multipoint session will also be received by the same socket on the local host. A value of TRUE causes loopback reception to occur while a value of FALSE prohibits this.
SIO_MULTICAST_SCOPE (opcode setting: I, T==1)
Specifies the scope over which multicast transmissions will occur. Scope is defined as the number of routed network segments to be covered. A scope of zero would indicate that the multicast transmission would not be placed "on the wire" but could be disseminated across sockets within the local host. A scope value of one (the default) indicates that the transmission will be placed on the wire, but will not cross any routers. Higher scope values determine the number of routers that can be crossed. Note that this corresponds to the time-to-live (TTL) parameter in IP multicasting.
SIO_SET_QOS (opcode setting: I, T==1)
Associate the supplied QOS structure with the socket. No output buffer is required, the QOS structure will be obtained from the input buffer. The WSAENOPROTOOPT error code is indicated for service providers which do not support QOS.
SIO_SET_GROUP_QOS (opcode setting: I, T==1)
Reserved for future use with socket groups: Establish the supplied QOS structure with the socket group to which this socket belongs. No output buffer is required, the QOS structure will be obtained from the input buffer. The WSAENOPROTOOPT error code is indicated for service providers which do not support QOS, or if the socket descriptor specified is not the creator of the associated socket group.
SIO_TRANSLATE_HANDLE (opcode setting: I, O, T==1)
To obtain a corresponding handle for socket s that is valid in the context of a companion interface (for example, TH_NETDEV and TH_TAPI). A manifest constant identifying the companion interface along with any other needed parameters are specified in the input buffer. The corresponding handle will be available in the output buffer upon completion of this function. Refer to the appropriate section in the Windows Sockets 2 Protocol-Specific Annex and/or documentation for the particular companion interface for additional details. The WSAENOPROTOOPT error code is indicated for service providers which do not support this ioctl for the specified companion interface. This ioctl retrieves the handle associated using SIO_TRANSLATE_HANDLE.

It is recommend that the Component Object Model (COM) be used instead of this ioctl to discover and track other interfaces that might be supported by a socket. his ioctl is present for (reverse) compatibility with systems where COM is not available or cannot be used for some other reason.

SIO_ROUTING_INTERFACE_QUERY (opcode setting: I, O, T==1)
To obtain the address of the local interface (represented as SOCKADDR structure) which should be used to send to the remote address specified in the input buffer (as SOCKADDR). Remote multicast addresses may be submitted in the input buffer to get the address of the preferred interface for multicast transmission. In any case, the interface address returned may be used by the application in a subsequent bind request.

Note that routes are subject to change. Therefore, Windows Socket SPI clients cannot rely on the information returned by SIO_ROUTING_INTERFACE_QUERY to be persistent. SPI clients may register for routing change notifications using the SIO_ROUTING_INTERFACE_CHANGE IOCTL which provides for notification via either overlapped IO or FD_ROUTING_INTERFACE_CHANGE event. The following sequence of actions can be used to guarantee that the Windows Socket SPI client always has current routing interface information for a given destination:

  1. issue SIO_ROUTING_INTERFACE_CHANGE IOCTL
  2. issue SIO_ROUTING_INTERFACE_QUERY IOCTL
  3. whenever SIO_ROUTING_INTERFACE_CHANGE IOCTL notifies the WinSock SPI client of routing change (either via overlapped IO or by signaling FD_ROUTING_INTERFACE_CHANGE event), the whole sequence of actions should be repeated.

If output buffer is not large enough to contain the interface address, SOCKET_ERROR is returned as the result of this IOCTL and WSPGetLastError returns WSAEFAULT. The required size of the output buffer will be returned in lpcbBytesReturned in this case. Note the WSAEFAULT error code is also returned if the lpvInBuffer, lpvOutBuffer or lpcbBytesReturned parameter is not totally contained in a valid part of the user address space.

If the destination address specified in the input buffer cannot be reached via any of the available interfaces, SOCKET_ERROR is returned as the result of this IOCTL and WSAGetLastError returns WSAENETUNREACH or even WSAENETDOWN if all of the network connectivity is lost.

SIO_ROUTING_INTERFACE_CHANGE (opcode setting: I, T==1)
To receive notification of the interface change that should be used to reach the remote address in the input buffer (specified as a SOCKADDR structure). No output information will be provided upon completion of this IOCTL; the completion merely indicates that routing interface for a given destination has changed and should be queried again via SIO_ROUTING_INTERFACE_QUERY.

It is assumed (although not required) that the Windows Socket SPI client uses overlapped IO to be notified of routing interface change via completion of SIO_ROUTING_INTERFACE_CHANGE request. Alternatively, if the SIO_ROUTING_INTERFACE_CHANGE IOCTL is issued on non-blocking socket AND without overlapped parameters (lpOverlapped / CompletionRoutine are set NULL), it will complete immediately with error WSAEWOULDBLOCK, and the Windows Socket SPI client can then wait for routing change events using a call to WSPEventSelect or WSPAsyncSelect with FD_ROUTING_INTERFACE_CHANGE bit set in the network event bitmask

It is recognized that routing information remains stable in most cases so that requiring the Windows Socket SPI client to keep multiple outstanding IOCTLs to get notifications about all destinations that it is interested in as well as having service provider to keep track of all them will unnecessarily tie significant system resources. This situation can be avoided by extending the meaning of the input parameters and relaxing the service provider requirements as follows:

The Windows Socket SPI client can specify a protocol family specific wildcard address (same as one used in bind call when requesting to bind to any available address) to request notifications of any routing changes. This allows the Windows Socket SPI client to keep only one outstanding SIO_ROUTING_INTERFACE_CHANGE for all the sockets/destinations it has and then use SIO_ROUTING_INTERFACE_QUERY to get the actual routing information

Service provider can opt to ignore the information supplied by the Windows Socket SPI client in the input buffer of the SIO_ROUTING_INTERFACE_CHANGE (as though the Windows Socket SPI client specified a wildcard address) and complete the SIO_ROUTING_INTERFACE_CHANGE IOCTL or signal FD_ROUTING_INTERFACE_CHANGE event in the event of any routing information change (not just the route to the destination specified in the input buffer).

SIO_ADDRESS_LIST_QUERY (opcode setting: I, O, T==1)
To obtain a list of local transport addresses of socket's protocol family to which the WinSock SPI client can bind. The list returned in the output buffer using the following format:
typedef struct _SOCKET_ADDRESS_LIST {
….INT iAddressCount;
….SOCKET_ADDRESS Address[1];
} SOCKET_ADDRESS_LIST, FAR * LPSOCKET_ADDRESS_LIST;
Members:
….iAddressCount- number of address structures in the list;
….Address- array of protocol family specific address structures.

Note that in Win32 Plug-n-Play environments addresses can be added/removed dynamically. Therefore, Windows Socket SPI clients cannot rely on the information returned by SIO_ADDRESS_LIST_QUERY to be persistent. Windows Socket SPI clients may register for address change notifications via the SIO_ADDRESS_LIST_CHANGE IOCTL which provides for notification via either overlapped IO or FD_ADDRESS_LIST_CHANGE event. The following sequence of actions can be used to guarantee that the Windows Socket SPI client always has current address list information:

  1. issue SIO_ADDRESS_LIST_CHANGE IOCTL
  2. issue SIO_ADDRESS_LIST_QUERY IOCTL
  3. whenever SIO_ADDRESS_LIST_CHANGE IOCTL notifies the WinSock SPI client of address list change (either via overlapped IO or by signaling FD_ADDRESS_LIST_CHANGE event), the whole sequence of actions should be repeated.

If output buffer is not large enough to contain the address list, SOCKET_ERROR is returned as the result of this IOCTL and WSPGetLastError returns WSAEFAULT. The required size of the output buffer will be returned in lpcbBytesReturned in this case. Note the WSAEFAULT error code is also returned if the lpvInBuffer, lpvOutBuffer or lpcbBytesReturned parameter is not totally contained in a valid part of the user address space.

SIO_ADDRESS_LIST_CHANGE (opcode setting: T==1)
To receive notification of changes in the list of local transport addresses of socket's protocol family to which the Windows Socket SPI client can bind. No output information will be provided upon completion of this IOCTL; the completion merely indicates that list of available local address has changed and should be queried again via SIO_ADDRESS_LIST_QUERY.

It is assumed (although not required) that the Windows Socket SPI client uses overlapped IO to be notified of change via completion of SIO_ADDRESS_LIST_CHANGE request. Alternatively, if the SIO_ADDRESS_LIST_CHANGE IOCTL is issued on non-blocking socket AND without overlapped parameters (lpOverlapped / lpCompletionRoutine are set to NULL), it will complete immediately with error WSAEWOULDBLOCK. The Windows Socket SPI client can then wait for address list change events via call to WSPEventSelect or WSPAsyncSelect with FD_ADDRESS_LIST_CHANGE bit set in the network event bitmask.

SIO_QUERY_PNP_TARGET_HANDLE (opcode setting: O, T==1)
To obtain socket descriptor of the next provider in the chain on which current socket depends in PnP sense. This IOCTL is invoked by the Windows Socket 2 DLL ONLY on sockets of Non-IFS service providers created via WPUCreateSocketHandle call. The provider should return in the output buffer the socket handle of the next provider in the chain on which given socket handle depends in PnP sense (e.g. the removal of the device that supports the underlying handle will result in invalidation of the handle above it in the chain).

If an overlapped operation completes immediately, this function returns a value of zero and the lpcbBytesReturned parameter is updated with the number of bytes in the output buffer. If the overlapped operation is successfully initiated and will complete later, this function returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpcbBytesReturned is not updated. When the overlapped operation completes the amount of data in the output buffer is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSPGetOverlappedResult.

When called with an overlapped socket, the lpOverlapped parameter must be valid for the duration of the overlapped operation. The WSAOVERLAPPED structure has the following form:

typedef struct _WSAOVERLAPPED {
    DWORD       Internal;      // reserved
    DWORD       InternalHigh;  // reserved
    DWORD       Offset;        // reserved
    DWORD       OffsetHigh;    // reserved
    WSAEVENT    hEvent;
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;

If the lpCompletionRoutine parameter is NULL, the service provider signals the hEvent field of lpOverlapped when the overlapped operation completes if it contains a valid event object handle. The Windows Sockets SPI client can use WSPGetOverlappedResult to poll or wait on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the Windows Sockets SPI client to pass context information to the completion routine. A client that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

It is the service provider's responsibility to arrange for invocation of the client-specified completion routine when the overlapped operation completes. Since the completion routine must be executed in the context of the same thread that initiated the overlapped operation, it cannot be invoked directly from the service provider. The WS2_32.DLL offers an asynchronous procedure call (APC) mechanism to facilitate invocation of completion routines.

A service provider arranges for a function to be executed in the proper thread thread and process context by calling WPUQueueApc. This function can be called from any process and thread context, even a context different from the thread and process that was used to initiate the overlapped operation.

WPUQueueApc takes as input parameters a pointer to a WSATHREADID structure (supplied to the provider through the lpThreadId input parameter), a pointer to an APC function to be invoked, and a 32-bit context value that is subsequently passed to the APC function. Because only a single 32-bit context value is available, the APC function cannot itself be the client-specified completion routine. The service provider must instead supply a pointer to its own APC function which uses the supplied context value to access the needed result information for the overlapped operation, and then invokes the client-specified completion routine.

The prototype for the client-supplied completion routine is as follows:

void CALLBACK CompletionRoutine (
 IN    DWORD dwError,
 IN    DWORD cbTransferred,
 IN    LPWSAOVERLAPPED lpOverlapped,
 IN    DWORD dwFlags
);

CompletionRoutine is a placeholder for a client supplied function. dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. cbTransferred specifies the number of bytes returned. Currently there are no flag values defined and dwFlags will be zero. This function does not return a value.

Returning from this function allows invocation of another pending completion routine for this socket. The completion routines can be called in any order, though not necessarily in the same order that the overlapped operations are completed.

Compatibility

The ioctl codes with T == 0 are a subset of the ioctl codes used in Berkeley sockets. In particular, there is no command which is equivalent to FIOASYNC.

Return Values

If no error occurs and the operation has completed immediately, WSPIoctl returns zero. Note that in this case the completion routine, if specified, will have already been queued. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno. The error code WSA_IO_PENDING indicates that an overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that no overlapped operation was initiated and no completion indication will occur.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The lpvInBuffer, lpvOutBuffer or lpcbBytesReturned argument is not totally contained in a valid part of the user address space, or the cbInBuffer or cbOutBuffer argument is too small.
WSAEINVAL | dwIoControlCode is not a valid command, or a supplied input parameter is not acceptable, or the command is not applicable to the type of socket supplied.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAENOTSOCK | The descriptor s is not a socket.
WSAEOPNOTSUPP | The specified ioctl command cannot be realized. For example, the flow specifications specified in SIO_SET_QOS or SIO_SET_GROUP_QOS cannot be satisfied.
WSA_IO_PENDING | An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSAEWOULDBLOCK | The socket is marked as nonblocking and the requested operation would block.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPSocket, WSPSetSockOpt, WSPGetSockOpt, WPUQueueApc


WSPJoinLeaf

The WSPJoinLeaf function joins a leaf node into a multipoint session, exchanges connect data, and specifies needed quality of service based on the supplied flow specifications.

SOCKET WSPJoinLeaf (
  SOCKET s,
  const struct sockaddr FAR * name,
  int namelen,
  LPWSABUF lpCallerData,
  LPWSABUF lpCalleeData,
  LPQOS lpSQOS,
  LPQOS lpGQOS,
  DWORD dwFlags,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a multipoint socket.
name
[in] The name of the peer to which the socket is to be joined.
namelen
[in] The length of the name.
lpCallerData
[in] A pointer to the user data that is to be transferred to the peer during multipoint session establishment.
lpCalleeData
[out] A pointer to the user data that is to be transferred back from the peer during multipoint session establishment.
lpSQOS
[in] A pointer to the flow specifications for socket s, one for each direction.
lpGQOS
[in] Reserved for future use with socket groups: A pointer to the flow specifications for the socket group (if applicable).
dwFlags
[in] Flags to indicate that the socket is acting as a sender, receiver, or both.
lpErrno
[out] A pointer to the error code.

Remarks

This function is used to join a leaf node to a multipoint session, and to perform a number of other ancillary operations that occur at session join time as well. If the socket, s, is unbound, unique values are assigned to the local association by the system, and the socket is marked as bound.

WSPJoinLeaf has the same parameters and semantics as WSPConnect except that it returns a socket descriptor (as in WSPAccept), and it has an additional dwFlags parameter. Only multipoint sockets created using WSPSocket with appropriate multipoint flags set can be used for input parameter s in this function. If the socket is in the nonblocking mode, the returned socket descriptor will not be useable until after a corresponding FD_CONNECT indication on the original socket s has been received, except that closesocket can be invoked on this new socket descriptor to cancel a pending join operation. A root node in a multipoint session can call WSPJoinLeaf one or more times in order to add a number of leaf nodes, however at most one multipoint connection request can be outstanding at a time. Refer to SPI: Protocol-Independent Multicast and Multipoint for additional information.

For nonblocking sockets it is often not possible to complete the connection immediately. In such a case, this function returns an as-yet unusable socket descriptor and the operation proceeds. There is no error code such as WSAEWOULDBLOCK in this case, since the function has effectively returned a "successful start" indication. When the final outcome success or failure becomes known, it may be reported through WSPAsyncSelect or WSPEventSelect depending on how the client registers for notification on the original socket s. In either case, the notification is announced with FD_CONNECT and the error code associated with the FD_CONNECT indicates either success or a specific reason for failure. Note that WSPSelect cannot be used to detect completion notification for WSAJoinLeaf.

The socket descriptor returned by WSPJoinLeaf is different depending on whether the input socket descriptor, s, is a c_root or a c_leaf. When used with a c_root socket, the name parameter designates a particular leaf node to be added and the returned socket descriptor is a c_leaf socket corresponding to the newly added leaf node. (As is described in section Descriptor Allocation, when new socket descriptors are allocated IFS providers must call WPUModifyIFSHandle and non-IFS providers must call WPUCreateSocketHandle). The newly created socket has the same properties as s including asynchronous events registered with WSPAsyncSelect or with WSPEventSelect, but not including the c_root socket's group ID, if any. It is not intended to be used for exchange of multipoint data, but rather is used to receive network event indications (for example, FD_CLOSE) for the connection that exists to the particular c_leaf. Some multipoint implementations can also allow this socket to be used for "side chats" between the root and an individual leaf node. An FD_CLOSE indication will be received for this socket if the corresponding leaf node calls WSPCloseSocket to drop out of the multipoint session. Symmetrically, invoking WSPCloseSocket on the c_leaf socket returned from WSPJoinLeaf will cause the socket in the corresponding leaf node to get FD_CLOSE notification.

When WSPJoinLeaf is invoked with a c_leaf socket, the name parameter contains the address of the root node (for a rooted control scheme) or an existing multipoint session (nonrooted control scheme), and the returned socket descriptor is the same as the input socket descriptor. In other words, a new socket descriptor is not allocated. In a rooted control scheme, the root application would put its c_root socket in the listening mode by calling WSPListen. The standard FD_ACCEPT notification will be delivered when the leaf node requests to join itself to the multipoint session. The root application uses the usual WSPAccept functions to admit the new leaf node. The value returned from WSPAccept is also a c_leaf socket descriptor just like those returned from WSPJoinLeaf. To accommodate multipoint schemes that allow both root-initiated and leaf-initiated joins, it is acceptable for a c_root socket that is already in listening mode to be used as an input to WSPJoinLeaf.

The Windows Sockets SPI client is responsible for allocating any memory space pointed to directly or indirectly by any of the parameters it specifies.

The lpCallerData is a value parameter which contains any user data that is to be sent along with the multipoint session join request. If lpCallerData is NULL, no user data will be passed to the peer. The lpCalleeData is a result parameter which will contain any user data passed back from the peer as part of the multipoint session establishment. lpCalleeData->len initially contains the length of the buffer allocated by the Windows Sockets SPI client and pointed to by lpCalleeData->buf. lpCalleeData->len will be set to zero if no user data has been passed back. The lpCalleeData information will be valid when the multipoint join operation is complete. For blocking sockets, this will be when the WSPJoinLeaf function returns. For nonblocking sockets, this will be after the FD_CONNECT notification has occurred on the original socket s. If lpCalleeData is NULL, no user data will be passed back. The exact format of the user data is specific to the address family to which the socket belongs and/or the applications involved.

At multipoint session establishment time, a Windows Sockets SPI client can use the lpSQOS and/or lpGQOS parameters to override any previous QOS specification made for the socket through WSPIoctl with either the SIO_SET_QOS or SIO_SET_GROUP_QOS opcodes.

lpSQOS specifies the flow specifications for socket s, one for each direction, followed by any additional provider-specific parameters. If either the associated transport provider in general or the specific type of socket in particular cannot honor the QOS request, an error will be returned as indicated below. The sending or receiving flow specification values will be ignored, respectively, for any unidirectional sockets. If no provider-specific parameters are supplied, the buf and len fields of lpSQOS->ProviderSpecific should be set to NULL and zero, respectively. A NULL value for lpSQOS indicates no application supplied QOS.

Reserved for future use with socket groups: lpGQOS specifies the flow specifications for the socket group (if applicable), one for each direction, followed by any additional provider-specific parameters. If no provider-specific parameters are supplied, the buf and len fields of lpGQOS->ProviderSpecific should be set to NULL and zero, respectively. A NULL value for lpGQOS indicates no application-supplied group QOS. This parameter will be ignored if s is not the creator of the socket group.

The dwFlags parameter is used to indicate whether the socket will be acting only as a sender (JL_SENDER_ONLY), only as a receiver (JL_RECEIVER_ONLY), or both (JL_BOTH).

Comments

When connected sockets break (that is, become closed for whatever reason), they should be discarded and recreated. It is safest to assume that when things go awry for any reason on a connected socket, the Windows Sockets SPI client must discard and recreate the needed sockets in order to return to a stable point.

Return Values

If no error occurs, WSPJoinLeaf returns a value of type SOCKET which is a descriptor for the newly created multipoint socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code is available in lpErrno.

On a blocking socket, the return value indicates success or failure of the join operation.

With a nonblocking socket, successful initiation of a join operation is indicated by a return value of a valid socket descriptor. Subsequently, an FD_CONNECT indication is given when the join operation completes, either successfully or otherwise. The error code associated with the FD_CONNECT indicates the success or failure of the WSPJoinLeaf.

Also, until the multipoint session join attempt completes all subsequent calls to WSPJoinLeaf on the same socket will fail with the error code WSAEALREADY. After the WSAJoinLeaf completes successfully a subsequent attempt will usually fail with the error code WSAEISCONN. An exception to the WSAEISCONN rule occurs for a c_root socket that allows root-initiated joins. In such a case another join may be initiated after a prior WSAJoinLeaf completes.

If the return error code indicates the multipoint session join attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the Windows Sockets SPI client can call WSPJoinLeaf again for the same socket.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs at the time of bind, but could be delayed until this function if the bind was to a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be "committed" at the time of this function.
WSAEINTR | The (blocking) call was canceled through WSPCancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAEALREADY | A nonblocking WSPJoinLeaf call is in progress on the specified socket.
WSAEADDRNOTAVAIL | The remote address is not a valid address (for example, ADDR_ANY).
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED | The attempt to join was forcefully rejected.
WSAEFAULT | The name or the namelen argument is not a valid part of the user address space, the namelen argument is too small, the buffer length for lpCalleeData, lpSQOS, and lpGQOS are too small, or the buffer length for lpCallerData is too large.
WSAEISCONN | The socket is already member of the multipoint session.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSAENOBUFS | No buffer space is available. The socket cannot be joined.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The flow specifications specified in lpSQOS and lpGQOS cannot be satisfied.
WSAEPROTONOSUPPORT | The lpCallerData augment is not supported by the service provider.
WSAETIMEDOUT | Attempt to join timed out without establishing a multipoint session.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPBind, WSPSelect, WSPAccept, WSPAsyncSelect, WSPEventSelect, WSPSocket


WSPListen

The WSPListen function establishes a socket to listen for incoming connections.

int WSPListen (
  SOCKET s,
  int backlog,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a bound, unconnected socket.
backlog
[in] The maximum length to which the queue of pending connections can grow. If this value is SOMAXCONN, then the service provider should set the backlog to a maximum "reasonable" value. There is no standard provision to find out the actual backlog value.
lpErrno
[out] A pointer to the error code.

Remarks

To accept connections, a socket is first created with WSPSocket bound to a local address with WSPBind, a backlog for incoming connections is specified with WSPListen, and then the connections are accepted with WSPAccept. WSPListen applies only to sockets that are connection oriented (for example, SOCK_STREAM). The socket s is put into "passive'' mode where incoming connection requests are acknowledged and queued pending acceptance by the Windows Sockets SPI client.

This function is typically used by servers that could have more than one connection request at a time: if a connection request arrives with the queue full, the client will receive an error with an indication of WSAECONNREFUSED.

WSPListen should continue to function rationally when there are no available descriptors. It should accept connections until the queue is emptied. If descriptors become available, a later call to WSPListen or WSPAccept will re-fill the queue to the current or most recent "backlog'', if possible, and resume listening for incoming connections.

A Windows Sockets SPI client can call WSPListen more than once on the same socket. This has the effect of updating the current backlog for the listening socket. Should there be more pending connections than the new backlog value, the excess pending connections will be reset and dropped.

Compatibility

backlog is limited (silently) to a reasonable value as determined by the service provider. Illegal values are replaced by the nearest legal value. There is no standard provision to find out the actual backlog value.

Return Values

If no error occurs, WSPListen returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEADDRINUSE | The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs at the time of bind, but could be delayed until this function if the bind was to a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be "committed" at the time of this function.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAEINVAL | The socket has not been bound with WSPBind.
WSAEISCONN | The socket is already connected.
WSAEMFILE | No more socket descriptors are available.
WSAENOBUFS | No buffer space is available.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | The referenced socket is not of a type that supports the WSPListen operation.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPAccept, WSPConnect, WSPSocket


WSPRecv

The WSPRecv function receives data on a socket.

int WSPRecv (
  SOCKET s,
  LPWSABUF lpBuffers,
  DWORD dwBufferCount,
  LPDWORD lpNumberOfBytesRecvd,
  LPDWORD lpFlags,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  LPWSATHREADID lpThreadId,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a connected socket.
lpBuffers
[in/out] A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length of the buffer.
dwBufferCount
[in] The number of WSABUF structures in the lpBuffers array.
lpNumberOfBytesRecvd
[out] A pointer to the number of bytes received by this call.
lpFlags
[in/out] A pointer to flags.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for non-overlapped structures).
lpCompletionRoutine
[in] A pointer to the completion routine called when the receive operation has been completed (ignored for non-overlapped structures).
lpThreadId
[in] A pointer to a WSATHREADID structure to be used by the provider in a subsequent call to WPUQueueApc. The provider should store the referenced WSATHREADID structure (not the pointer to same) until after the WPUQueueApc function returns.
lpErrno
[out] A pointer to the error code.

Remarks

WSPRecv is used on connected sockets or bound connectionless sockets specified by the s parameter and is used to read incoming data. The socket's local address must be known. This may be done explicitly through WSPBind or implicitly through WSPAccept, WSPConnect, WSPSendTo, or WSPJoinLeaf.

For connected, connectionless sockets, this function restricts the addresses from which received messages are accepted. The function only returns messages from the remote address specified in the connection. Messages from other addresses are (silently) discarded.

For overlapped sockets WSPRecv is used to post one or more buffers into which incoming data will be placed as it becomes available, after which the Windows Sockets SPI client-specified completion indication (invocation of the completion routine or setting of an event object) occurs. If the operation does not complete immediately, the final completion status is retrieved through the completion routine or WSPGetOverlappedResult.

If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a nonoverlapped socket.

For nonoverlapped sockets, the lpOverlapped, lpCompletionRoutine, and lpThreadId parameters are ignored. Any data which has already been received and buffered by the transport will be copied into the supplied user buffers. For the case of a blocking socket with no data currently having been received and buffered by the transport, the call will block until data is received. Windows Sockets 2 does not define any standard blocking timeout mechanism for this function. For protocols acting as byte-stream protocols the stack tries to return as much data as possible subject to the supplied buffer space and amount of received data available. However, receipt of a single byte is sufficient to unblock the caller. There is no guarantee that more than a single byte will be returned. For protocols acting as message-oriented, a full message is required to unblock the caller.

Whether or not a protocol is acting as byte-stream is determined by the setting of XP1_MESSAGE_ORIENTED and XP1_PSEUDO_STREAM in its WSAPROTOCOL_INFO structure and the setting of the MSG_PARTIAL flag passed in to this function (for protocols that support it). The relevant combinations are summarized in the following table (an asterisk (*) indicates that the setting of this bit does not matter in this case).

XP1_MESSAGE _ORIENTED | XP1_PSEUDO _STREAM | MSG_PARTIAL | Acts as
not set | * | * | byte-stream
* | set | * | byte-stream
set | not set | set | byte-stream
set | not set | not set | message-oriented

The supplied buffers are filled in the order in which they appear in the array pointed to by lpBuffers, and the buffers are packed so that no holes are created.

The array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation completes in an overlapped manner, it is the service provider's responsibility to capture this array of pointers to WSABUF structures before returning from this call. This enables Windows Sockets SPI clients to build stack-based WSABUF arrays.

For byte stream-style sockets (for example, type SOCK_STREAM), incoming data is placed into the buffers until the buffers are filled, the connection is closed, or internally buffered data is exhausted. Regardless of whether or not the incoming data fills all the buffers, the completion indication occurs for overlapped sockets. For message-oriented sockets (for example, type SOCK_DGRAM), an incoming message is placed into the supplied buffers, up to the total size of the buffers supplied, and the completion indication occurs for overlapped sockets. If the message is larger than the buffers supplied, the buffers are filled with the first part of the message. If the MSG_PARTIAL feature is supported by the service provider, the MSG_PARTIAL flag is set in lpflags and subsequent receive operation(s) can be used to retrieve the rest of the message. If MSG_PARTIAL is not supported but the protocol is reliable, WSPRecv generates the error WSAEMSGSIZE and a subsequent receive operation with a larger buffer can be used to retrieve the entire message. Otherwise, (that is, the protocol is unreliable and does not support MSG_PARTIAL), the excess data is lost, and WSPRecv generates the error WSAEMSGSIZE.

For connection-oriented sockets, WSPRecv can indicate the graceful termination of the virtual circuit in one of two ways, depending on whether the socket is a byte stream or message oriented. For byte streams, zero bytes having been read indicates graceful closure and that no more bytes will ever be read. For message-oriented sockets, where a zero byte message is often allowable, a return error code of WSAEDISCON is used to indicate graceful closure. In any case a return error code of WSAECONNRESET indicates an abortive close has occurred.

lpFlags can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the lpFlags parameter. The latter is constructed by or-ing any of the following values:

Value | Meaning
MSG_PEEK | Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue. This flag is valid only for nonoverlapped sockets.
MSG_OOB | Process out-of-band data (See section. DECnet Out-Of-band data for a discussion of this topic.)
MSG_PARTIAL | This flag is for message-oriented sockets only. On output, indicates that the data supplied is a portion of the message transmitted by the sender. Remaining portions of the message will be supplied in subsequent receive operations. A subsequent receive operation with MSG_PARTIAL flag cleared indicates end of sender's message. As an input parameter, MSG_PARTIAL indicates that the receive operation should complete even if only part of a message has been received by the service provider.

Overlapped socket I/O

If an overlapped operation completes immediately, WSPRecv returns a value of zero and the lpNumberOfBytesRecvd parameter is updated with the number of bytes received and the flag bits pointed by the lpFlags parameter are also updated. If the overlapped operation is successfully initiated and will complete later, WSPRecv returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd and lpFlags are not updated. When the overlapped operation completes the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSPGetOverlappedResult. Flag values are obtained either through the dwFlags parameter of the completion routine, or by examining the lpdwFlags parameter of WSPGetOverlappedResult.

Providers must allow this function to be called from within the completion routine of a previous WSPRecv, WSPRecvFrom, WSPSend or WSPSendTo function. However, for a given socket, I/O completion routines can not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate overlapped structure. The WSAOVERLAPPED structure has the following form:

typedef struct _WSAOVERLAPPED {
    DWORD     Internal;        // reserved
    DWORD     InternalHigh;    // reserved
    DWORD     Offset;          // reserved
    DWORD     OffsetHigh;      // reserved
    WSAEVENT  hEvent;
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;

If the lpCompletionRoutine parameter is NULL, the service provider signals the hEvent field of lpOverlapped when the overlapped operation completes if it contains a valid event object handle. The Windows Sockets SPI client can use WSPGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the Windows Sockets SPI client to pass context information to the completion routine. A client that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

It is the service provider's responsibility to arrange for invocation of the client-specified completion routine when the overlapped operation completes. Since the completion routine must be executed in the context of the same thread that initiated the overlapped operation, it cannot be invoked directly from the service provider. The WS2_32.DLL offers an asynchronous procedure call (APC) mechanism to facilitate invocation of completion routines.

A service provider arranges for a function to be executed in the proper thread and process context by calling WPUQueueApc, which was used to initiate the overlapped operation. This function can be called from any process and thread context, even a context different from the thread and process that was used to initiate the overlapped operation.

WPUQueueApc takes as input parameters a pointer to a WSATHREADID structure (supplied to the provider through the lpThreadId input parameter), a pointer to an APC function to be invoked, and a 32-bit context value that is subsequently passed to the APC function. Because only a single 32-bit context value is available, the APC function cannot itself be the client-specified completion routine. The service provider must instead supply a pointer to its own APC function which uses the supplied context value to access the needed result information for the overlapped operation, and then invokes the client-specified completion routine.

The prototype for the client-supplied completion routine is as follows:

void CALLBACK CompletionRoutine (
 IN    DWORD dwError,
 IN    DWORD cbTransferred,
 IN    LPWSAOVERLAPPED lpOverlapped,
 IN    DWORD dwFlags
);

CompletionRoutine is a placeholder for a client-supplied function name. dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. cbTransferred specifies the number of bytes received. dwFlags contains information that would have appeared in lpFlags if the receive operation had completed immediately. This function does not return a value.

The completion routines can be called in any order, not necessarily in the same order the overlapped operations are completed. However, the posted buffers are guaranteed to be filled in the same order they are supplied.

Return Values

If no error occurs and the receive operation has completed immediately, WSPRecv returns zero. Note that in this case the completion routine, if specified, will have already been queued. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that no overlapped operations was initiated and no completion indication will occur.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAENOTCONN | The socket is not connected.
WSAEINTR | The (blocking) call was canceled through WSPCancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAEFAULT | The lpBuffers argument is not totally contained in a valid part of the user address space.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to WSPRecv on a socket after WSPShutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.
WSAEWOULDBLOCK | Overlapped sockets: There are too many outstanding overlapped I/O requests. Non-overlapped sockets: The socket is marked as nonblocking and the receive operation cannot be completed immediately.
WSAEMSGSIZE | The message was too large to fit into the specified buffer and (for unreliable protocols only) any trailing portion of the message that did not fit into the buffer has been discarded.
WSAEINVAL | The socket has not been bound (for example, with WSPBind)or the socket is not created with the overlapped flag.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure.
WSAECONNRESET | The virtual circuit was reset by the remote side.
WSAEDISCON | Socket s is message oriented and the virtual circuit was gracefully closed by the remote side.
WSA_IO_PENDING | An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSA_OPERATION_ABORTED | The overlapped operation has been canceled due to the closure of the socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WPUCloseEvent, WPUCreateEvent, WSPGetOverlappedResult, WSPSocket, WPUQueueApc


WSPRecvDisconnect

The WSPRecvDisconnect function terminates reception on a socket and retrieves the disconnect data, if the socket is connection oriented.

int WSPRecvDisconnect (
  SOCKET s,
  LPWSABUF lpInboundDisconnectData,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
lpInboundDisconnectData
[out] A pointer to a buffer into which disconnect data is to be copied.
lpErrno
[out] A pointer to the error code.

Remarks

WSPRecvDisconnect is used on connection-oriented sockets to disable reception, and retrieve any incoming disconnect data from the remote party.

After this function has been successfully issued, subsequent receives on the socket will be disallowed. This has no effect on the lower protocol layers. For TCP, the TCP window is not changed and incoming data will be accepted (but not acknowledged) until the window is exhausted. For UDP, incoming datagrams are accepted and queued. In no case will an ICMP error packet be generated.

To successfully receive incoming disconnect data, a Windows Sockets SPI client must use other mechanisms to determine that the circuit has been closed. For example, a client needs to receive an FD_CLOSE notification, or get a zero return value, or a WSAEDISCON error code from WSPRecv.

Note that WSPRecvDisconnect does not close the socket, and resources attached to the socket will not be freed until WSPCloseSocket is invoked.

Comments

WSPRecvDisconnect does not block regardless of the SO_LINGER setting on the socket.

A Windows Sockets SPI client should not rely on being able to re-use a socket after it has been WSPRecvDisconnected. In particular, a Windows Sockets provider is not required to support the use of WSPConnect on such a socket.

Return Values

If no error occurs, WSPRecvDisconnect returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The buffer referenced by the parameter lpInboundDisconnectData is too small.
WSAENOPROTOOPT | The disconnect data is not supported by the indicated protocol family.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only).
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPConnect, WSPSocket


WSPRecvFrom

The WSPRecvFrom function receives a datagram and store the source address.

int WSPRecvFrom (
  SOCKET s,
  LPWSABUF lpBuffers,
  DWORD dwBufferCount,
  LPDWORD lpNumberOfBytesRecvd,
  LPDWORD lpFlags,
  struct sockaddr FAR * lpFrom,
  LPINT lpFromlen,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  LPWSATHREADID lpThreadId,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
lpBuffers
[in/out] A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length of the buffer.
dwBufferCount
[in] The number of WSABUF structures in the lpBuffers array.
lpNumberOfBytesRecvd
[out] A pointer to the number of bytes received by this call.
lpFlags
[in/out] A pointer to flags.
lpFrom
[out] An optional pointer to a buffer which will hold the source address upon the completion of the overlapped operation.
lpFromlen
[in/out] A pointer to the size of the from buffer, required only if lpFrom is specified.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for non-overlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the receive operation has been completed (ignored for non-overlapped sockets).
lpThreadId
[in] A pointer to a WSATHREADID structure to be used by the provider in a subsequent call to WPUQueueApc. The provider should store the referenced WSATHREADID structure (not the pointer to same) until after the WPUQueueApc function returns.
lpErrno
[in/out] A pointer to the error code.

Remarks

WSPRecvFrom is used primarily on a connectionless socket specified by s. The socket must not be connected. The local address of the socket must be known. This may be done explicitly through WSPBind or implicitly through WSPSendTo or WSPJoinLeaf.

For overlapped sockets, this function is used to post one or more buffers into which incoming data will be placed as it becomes available on a (possibly connected) socket, after which the client-specified completion indication (invocation of the completion routine or setting of an event object) occurs. If the operation does not complete immediately, the final completion status is retrieved through the completion routine or WSPGetOverlappedResult. Also note that the values pointed to by lpFrom and lpFromlen are not updated until completion is indicated. Applications must not use or disturb these values until they have been updated, therefore the client must not use automatic (i.e stack-based) variables for these parameters.

If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a nonoverlapped socket.

For nonoverlapped sockets, the lpOverlapped, lpCompletionRoutine, and lpThreadId parameters are ignored. Any data which has already been received and buffered by the transport will be copied into the supplied user buffers. For the case of a blocking socket with no data currently having been received and buffered by the transport, the call will block until data is received according to the assigned blocking semantics for WSPRecv.

The supplied buffers are filled in the order in which they appear in the array pointed to by lpBuffers, and the buffers are packed so that no holes are created.

The array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation completes in an overlapped manner, it is the service provider's responsibility to capture this array of pointers to WSABUF structures before returning from this call. This enables Windows Sockets SPI clients to build stack-based WSABUF arrays.

For connectionless socket types, the address from which the data originated is copied to the buffer pointed by lpFrom. On input, the value pointed to by lpFromlen is initialized to the size of this buffer, and is modified on completion to indicate the actual size of the address stored there. As noted previously for overlapped sockets, the lpFrom and lpFromlen parameters are not updated until after the overlapped I/O has completed. The memory pointed to by these parameters must, therefore, remain available to the service provider and cannot be allocated on the Windows Sockets SPI client's stack frame. The lpFrom and lpFromlen parameters are ignored for connection-oriented sockets.

For byte stream-style sockets (for example, type SOCK_STREAM), incoming data is placed into the buffers until the buffers are filled, the connection is closed, or internally buffered data is exhausted. Regardless of whether or not the incoming data fills all the buffers, the completion indication occurs for overlapped sockets. For message-oriented sockets, a single incoming message is placed into the supplied buffers, up to the total size of the buffers supplied, and the completion indication occurs for overlapped sockets. If the message is larger than the buffers supplied, the buffers are filled with the first part of the message. If the MSG_PARTIAL feature is supported by the service provider, the MSG_PARTIAL flag is set in lpflags for the socket and subsequent receive operation(s) will retrieve the rest of the message. If MSG_PARTIAL is not supported but the protocol is reliable, WSPRecvFrom generates the error WSAEMSGSIZE and a subsequent receive operation with a larger buffer can be used to retrieve the entire message. Otherwise, (that is, the protocol is unreliable and does not support MSG_PARTIAL), the excess data is lost, and WSPRecvFrom generates the error WSAEMSGSIZE.

lpFlags can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the lpFlags parameter. The latter is constructed by or-ing any of the following values:

Value | Meaning
MSG_PEEK | Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue. This flag is valid only for nonoverlapped sockets.
MSG_OOB | Process out-of-band data (See section. DECnet Out-Of-band data for a discussion of this topic.)
MSG_PARTIAL | This flag is for message-oriented sockets only. On output, indicates that the data supplied is a portion of the message transmitted by the sender. Remaining portions of the message will be supplied in subsequent receive operations. A subsequent receive operation with MSG_PARTIAL flag cleared indicates end of sender's message. As an input parameter, MSG_PARTIAL indicates that the receive operation should complete even if only part of a message has been received by the service provider.

For message-oriented sockets, the MSG_PARTIAL bit is set in the lpFlags parameter if a partial message is received. If a complete message is received, MSG_PARTIAL is cleared in lpFlags. In the case of delayed completion, the value pointed to by lpFlags is not updated. When completion has been indicated the Windows Sockets SPI client should call WSPGetOverlappedResult and examine the flags pointed to by the lpdwFlags parameter.

Overlapped socket I/O

If an overlapped operation completes immediately, WSPRecv returns a value of zero and the lpNumberOfBytesRecvd parameter is updated with the number of bytes received and the flag bits pointed by the lpFlags parameter are also updated. If the overlapped operation is successfully initiated and will complete later, WSPRecv returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd and lpFlags is not updated. When the overlapped operation completes the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSPGetOverlappedResult. Flag values are obtained by examining the lpdwFlags parameter of WSPGetOverlappedResult.

Providers must allow this function to be called from within the completion routine of a previous WSPRecv, WSPRecvFrom, WSPSend or WSPSendTo function. However, for a given socket, I/O completion routines cannot be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate overlapped structure. The WSAOVERLAPPED structure has the following form:

typedef struct _WSAOVERLAPPED {
    DWORD        Internal;      // reserved
    DWORD        InternalHigh;  // reserved
    DWORD        Offset;        // reserved
    DWORD        OffsetHigh;    // reserved
    WSAEVENT     hEvent;
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;

If the lpCompletionRoutine parameter is NULL, the service provider signals the hEvent field of lpOverlapped when the overlapped operation completes if it contains a valid event object handle. A Windows Sockets SPI client can use WSPGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the Windows Sockets SPI client to pass context information to the completion routine. It is the service provider's responsibility to arrange for invocation of the client-specified completion routine when the overlapped operation completes. Since the completion routine must be executed in the context of the same thread that initiated the overlapped operation, it cannot be invoked directly from the service provider. The WS2_32.DLL offers an asynchronous procedure call (APC) mechanism to facilitate invocation of completion routines.

A service provider arranges for a function to be executed in the proper thread and process context by calling WPUQueueApc. This function can be called from any process and thread context, even a context different from the thread and process that was used to initiate the overlapped operation.

WPUQueueApc takes as input parameters a pointer to a WSATHREADID structure (supplied to the provider through the lpThreadId input parameter), a pointer to an APC function to be invoked, and a 32-bit context value that is subsequently passed to the APC function. Because only a single 32-bit context value is available, the APC function cannot itself be the client-specified completion routine. The service provider must instead supply a pointer to its own APC function which uses the supplied context value to access the needed result information for the overlapped operation, and then invokes the client-specified completion routine.

The prototype for the client-supplied completion routine is as follows:

void CALLBACK CompletionRoutine (
 IN    DWORD dwError,
 IN    DWORD cbTransferred,
 IN    LPWSAOVERLAPPED lpOverlapped,
 IN    DWORD dwFlags
);

CompletionRoutine is a placeholder for a client-supplied function name. dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. cbTransferred specifies the number of bytes received. dwFlags contains information that would have appeared in lpFlags if the receive operation had completed immediately. This function does not return a value.

The completion routines can be called in any order, though not necessarily in the same order that the overlapped operations are completed. However, the posted buffers are guaranteed to be filled in the same order they are supplied.

Return Values

If no error occurs and the receive operation has completed immediately, WSPRecvFrom returns zero. Note that in this case the completion routine, if specified will have already been queued. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that no overlapped operations was initiated and no completion indication will occur.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | The lpFromlen argument was invalid: the lpFrom buffer was too small to accommodate the peer address or lpbuffers is not totally contained within a valid part of the user address space.
WSAEINTR | The (blocking) call was canceled through WSPCancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | The socket has not been bound (for example, with WSPBind) or the socket is not created with the overlapped flag.
WSAEISCONN | The socket is connected. This function is not permitted with a connected socket, whether the socket is connection-oriented or connectionless.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to WSPRecvFrom on a socket after WSPShutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.
WSAEWOULDBLOCK | Overlapped sockets: There are too many outstanding overlapped I/O requests. Non-overlapped sockets: The socket is marked as nonblocking and the receive operation cannot be completed immediately.
WSAEMSGSIZE | The message was too large to fit into the specified buffer and (for unreliable protocols only) any trailing portion of the message that did not fit into the buffer has been discarded.
WSAECONNRESET | The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. The application should close the socket as it is no longer useable. On a UDP datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.
WSAEDISCON | Socket s is message oriented and the virtual circuit was gracefully closed by the remote side.
WSA_IO_PENDING | An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSA_OPERATION_ABORTED | The overlapped operation has been canceled due to the closure of the socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPSocket, WSPGetOverlappedResult, WPUQueueApc


WSPSelect

The WSPSelect function determines the status of one or more sockets.

int WSPSelect (
  int nfds,
  fd_set FAR * readfds,
  fd_set FAR * writefds,
  fd_set FAR * exceptfds,
  const struct timeval FAR * timeout,
  LPINT lpErrno
);

Parameters

nfds
[in] This argument is ignored and included only for the sake of compatibility.
readfds
[in/out] An optional pointer to a set of sockets to be checked for readability.
writefds
[in/out] An optional pointer to a set of sockets to be checked for writability
exceptfds
[in/out] An optional pointer to a set of sockets to be checked for errors.
timeout
[in] The maximum time for WSPSelect to wait, or NULL for a blocking operation.
lpErrno
[out] A pointer to the error code.

Remarks

This function is used to determine the status of one or more sockets. For each socket, the caller can request information on read, write or error status. The set of sockets for which a given status is requested is indicated by an fd_set structure. All entries in an fd_set correspond to sockets created by the service provider (that is, the WSAPROTOCOL_INFOW structures describing their protocols have the same providerId value). Upon return, the structures are updated to reflect the subset of these sockets which meet the specified condition, and WSPSelect returns the total number of sockets meeting the conditions. A set of macros is provided for manipulating an fd_set. These macros are compatible with those used in the Berkeley software, but the underlying representation is completely different.

The parameter readfds identifies those sockets which are to be checked for readability. If the socket is currently WSPListening, it will be marked as readable if an incoming connection request has been received, so that a WSPAccept is guaranteed to complete without blocking. For other sockets, readability means that queued data is available for reading so that a WSPRecv or WSPRecvfrom is guaranteed not to block.

For connection-oriented sockets, readability can also indicate that a close request has been received from the peer. If the virtual circuit was closed gracefully, then a WSPRecv will return immediately with zero bytes read. If the virtual circuit was reset, then a WSPRecv will complete immediately with an error code, such as WSAECONNRESET. The presence of out-of-band data will be checked if the socket option SO_OOBINLINE has been enabled (see WSPSetSockOpt).

The parameter writefds identifies those sockets which are to be checked for writability. If a socket is WSPConnecting, writability means that the connection establishment successfully completed. If the socket is not in the process of WSPConnecting, writability means that a WSPSend or WSPSendTo are guaranteed to succeed. However, they can block on a blocking socket if the len exceeds the amount of outgoing system buffer space available. [It is not specified how long these guarantees can be assumed to be valid, particularly in a multithreaded environment.]

The parameter exceptfds identifies those sockets which are to be checked for the presence of out-of-band data or any exceptional error conditions. Note that out-of-band data will only be reported in this way if the option SO_OOBINLINE is FALSE. If a socket is WSPConnecting (nonblocking), failure of the connect attempt is indicated in exceptfds. This specification does not define which other errors will be included.

Any two of readfds, writefds, or exceptfds can be given as NULL if no descriptors are to be checked for the condition of interest. At least one must be non-NULL, and any non-NULL descriptor set must contain at least one socket descriptor.

Summary: A socket will be identified in a particular set when WSPSelect returns if:

readfds: | If WSPListening, a connection is pending, WSPAccept will succeed Data is available for reading (includes OOB data if SO_OOBINLINE is enabled) Connection has been closed/reset/terminated
writefds: | If WSPConnecting (nonblocking), connection has succeeded Data can be sent
exceptfds: | If WSPConnecting (nonblocking), connection attempt failed OOB data is available for reading (only if SO_OOBINLINE is disabled)

Three macros and one upcall function are defined in the header file ws2spi.h for manipulating and checking the descriptor sets. The variable FD_SETSIZE determines the maximum number of descriptors in a set. (The default value of FD_SETSIZE is 64, which can be modified by #defining FD_SETSIZE to another value before #including ws2spi.h.) Internally, socket handles in a fd_set are not represented as bit flags as in Berkeley Unix. Their data representation is opaque. Use of these macros will maintain software portability between different socket environments. The macros to manipulate and check fd_set contents are:

FD_CLR(s, *set)
Removes the descriptor s from set.
FD_SET(s, *set)
Adds descriptor s to set.
FD_ZERO(*set)
Initializes the set to the NULL set.

The upcall function used to check the membership is:

int WPUFDIsSet ( SOCKET s, FD_SET FAR * set );
which will return nonzero if s is a member of the set or otherwise zero.

The parameter timeout controls how long the WSPSelect can take to complete. If timeout is a null pointer, WSPSelect will block indefinitely until at least one descriptor meets the specified criteria. Otherwise, timeout points to a struct timeval which specifies the maximum time that WSPSelect should wait before returning. When WSPSelect returns, the contents of the struct timeval are not altered. If the timeval is initialized to {0, 0}, WSPSelect will return immediately; this is used to "poll" the state of the selected sockets. If this is the case, then the WSPSelect call is considered nonblocking and the standard assumptions for nonblocking calls apply. For example, the blocking hook will not be called, and the Windows Sockets provider will not yield.

Return Values

WSPSelect returns the total number of descriptors which are ready and contained in the fd_set structures, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, a specific error code is available in lpErrno.

Comments

WSPSelect has no effect on the persistence of socket events registered with WSPAsyncSelect or WSPEventSelect.

Error Codes

WSAEFAULT | The Windows Sockets service provider was unable to allocated needed resources for its internal operations, or the readfds, writefds, exceptfds or timeval parameters are not part of the user address space.
WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | The timeout value is not valid, or all three descriptor parameters were NULL.
WSAEINTR | The (blocking) call was canceled through WSPCancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK | One of the descriptor sets contains an entry which is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPAccept, WSPConnect, WSPRecv, WSPRecvFrom, WSPSend, WSPSendTo, WSPEventSelect


WSPSend

The WSPSend function sends data on a connected socket.

int WSPSend (
  SOCKET s,
  LPWSABUF lpBuffers,
  DWORD dwBufferCount,
  LPDWORD lpNumberOfBytesSent,
  DWORD dwFlags,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  LPWSATHREADID lpThreadId,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a connected socket.
lpBuffers
[in] A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length of the buffer. This array must remain valid for the duration of the send operation.
dwBufferCount
[in] The number of WSABUF structures in the lpBuffers array.
lpNumberOfBytesSent
[out] A pointer to the number of bytes sent by this call.
dwFlags
[in] Specifies the way in which the call is made.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for non-overlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the send operation has been completed (ignored for non-overlapped sockets).
lpThreadId
[in] A pointer to a WSATHREADID structure to be used by the provider in a subsequent call to WPUQueueApc. The provider should store the referenced WSATHREADID structure (not the pointer to same) until after the WPUQueueApc function returns.
lpErrno
[out] A pointer to the error code.

Remarks

WSPSend is used to write outgoing data from one or more buffers on a connection-oriented socket specified by s. It can also be used, however, on connectionless sockets which have a stipulated default peer address established through the WSPConnect function.

For overlapped sockets (created using WSPSocket with flag WSA_FLAG_OVERLAPPED) this will occur using overlapped I/O, unless both lpOverlapped and lpCompletionRoutine are NULL in which case the socket is treated as a nonoverlapped socket. A completion indication will occur (invocation of the completion routine or setting of an event object) when the supplied buffer(s) have been consumed by the transport. If the operation does not complete immediately, the final completion status is retrieved through the completion routine or WSPGetOverlappedResult.

For nonoverlapped sockets, the parameters lpOverlapped, lpCompletionRoutine, and lpThreadId are ignored and WSPSend adopts the regular synchronous semantics. Data is copied from the supplied buffer(s) into the transport's buffer. If the socket is nonblocking and stream oriented, and there is not sufficient space in the transport's buffer, WSPSend will return with only part of the supplied buffers having been consumed. Given the same buffer situation and a blocking socket, WSPSend will block until all of the supplied buffer contents have been consumed.

The array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation completes in an overlapped manner, it is the service provider's responsibility to capture these WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays.

For message-oriented sockets, care must be taken not to exceed the maximum message size of the underlying provider, which can be obtained by getting the value of socket option SO_MAX_MSG_SIZE. If the data is too long to pass atomically through the underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.

Note that the successful completion of a WSPSend does not indicate that the data was successfully delivered.

dwFlags can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter. The latter is constructed by or-ing any of the following values:

Value | Meaning
MSG_DONTROUTE | Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag;.
MSG_OOB | Send out-of-band data (stream-style socket such as SOCK_STREAM only).
MSG_PARTIAL | Specifies that lpBuffers only contains a partial message. Note that the error code WSAEOPNOTSUPP will be returned which do not support partial message transmissions.

Overlapped socket I/O

If an overlapped operation completes immediately, WSPSend returns a value of zero and the lpNumberOfBytesSent parameter is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later, WSPSend returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent is not updated. When the overlapped operation completes the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSPGetOverlappedResult.

Providers must allow this function to be called from within the completion routine of a previous WSPRecv, WSPRecvFrom, WSPSend or WSPSendTo function. However, for a given socket, I/O completion routines cannot be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate overlapped structure. The WSAOVERLAPPED structure has the following form:

typedef struct _WSAOVERLAPPED {
    DWORD       Internal;        // reserved
    DWORD       InternalHigh;    // reserved
    DWORD       Offset;          // reserved
    DWORD       OffsetHigh;      // reserved
    WSAEVENT    hEvent;
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;

If the lpCompletionRoutine parameter is NULL, the service provider signals the hEvent field of lpOverlapped when the overlapped operation completes if it contains a valid event object handle. The Windows Sockets SPI client can use WSPGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the Windows Sockets SPI client to pass context information to the completion routine. A client that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

A service provider arranges for a function to be executed in the proper thread and process context by calling WPUQueueApc. This function can be called from any process and thread context, even a context different from the thread and process that was used to initiate the overlapped operation

A service provider arranges for a function to be executed in the proper thread by calling WPUQueueApc. Note that this function must be invoked while in the context of the same process (but not necessarily the same thread) that was used to initiate the overlapped operation. It is the service provider's responsibility to arrange for this process context to be active prior to calling WPUQueueApc.

WPUQueueApc takes as input parameters a pointer to a WSATHREADID structure (supplied to the provider through the lpThreadId input parameter), a pointer to an APC function to be invoked, and a 32-bit context value that is subsequently passed to the APC function. Because only a single 32-bit context value is available, the APC function cannot itself be the client-specified completion routine. The service provider must instead supply a pointer to its own APC function which uses the supplied context value to access the needed result information for the overlapped operation, and then invokes the client-specified completion routine.

The prototype for the client-supplied completion routine is as follows:

void CALLBACK CompletionRoutine (
 IN    DWORD dwError,
 IN    DWORD cbTransferred,
 IN    LPWSAOVERLAPPED lpOverlapped,
 IN    DWORD dwFlags
);

CompletionRoutine is a placeholder for a client supplied function name. dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. cbTransferred specifies the number of bytes sent. No flag values are currently defined and the dwFlags value will be zero. This function does not return a value.

The completion routines can be called in any order, though not necessarily in the same order that the overlapped operations are completed. However, the service provider guarantees to the client that posted buffers are sent in the same order they are supplied.

Return Values

If no error occurs and the send operation has completed immediately, WSPSend returns zero. Note that in this case the completion routine, if specified, will have already been queued. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that no overlapped operation was initiated and no completion indication will occur.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEACCES | The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The lpBuffers argument is not totally contained in a valid part of the user address space.
WSAENETRESET | The connection has been broken due to the remote host resetting.
WSAENOBUFS | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOTCONN | The socket is not connected.
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, MSG_PARTIAL is not supported, or the socket is unidirectional and supports only receive operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to WSPSend on a socket after WSPShutdown has been invoked with how set to SD_SEND or SD_BOTH.
WSAEWOULDBLOCK | Overlapped sockets: There are too many outstanding overlapped I/O requests. Non-overlapped sockets: The socket is marked as nonblocking and the send operation cannot be completed immediately.
WSAEMSGSIZE | The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
WSAEINVAL | The socket has not been bound with WSPBind, or the socket is not created with the overlapped flag.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure.
WSAECONNRESET | The virtual circuit was reset by the remote side.
WSA_OPERATION_ABORTED | The overlapped operation has been canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSPIoctl.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPSocket, WSPGetOverlappedResult, WPUQueueApc


WSPSendDisconnect

The WSPSendDisconnect function initiates termination of the connection for the socket and sends disconnect data.

int WSPSendDisconnect (
  SOCKET s,
  LPWSABUF lpOutboundDisconnectData,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
lpOutboundDisconnectData
[in] A pointer to the outgoing disconnect data.
lpErrno
[out] A pointer to the error code.

Remarks

WSPSendDisconnect is used on connection-oriented sockets to disable transmission, and to initiate termination of the connection along with the transmission of disconnect data, if any.

After this function has been successfully issued, subsequent sends are disallowed.

lpOutboundDisconnectData, if not NULL, points to a buffer containing the outgoing disconnect data to be sent to the remote party.

Note that WSPSendDisconnect does not close the socket, and resources attached to the socket will not be freed until WSPCloseSocket is invoked.

Comments

WSPSendDisconnect does not block regardless of the SO_LINGER setting on the socket.

A Windows Sockets SPI client should not rely on being able to re-use a socket after it has been WSPSendDisconnected. In particular, a Windows Sockets provider is not required to support the use of WSPConnect on such a socket.

Return Values

If no error occurs, WSPSendDisconnect returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAENOPROTOOPT | The parameter lpOutboundDisconnectData is not NULL, and the disconnect data is not supported by the service provider.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only).
WSAENOTSOCK | The descriptor is not a socket.
WSAEFAULT | The lpOutboundDisconnectData argument is not totally contained in a valid part of the user address space.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPConnect, WSPSocket


WSPSendTo

The WSPSendTo function sends data to a specific destination using overlapped I/O.

int WSPSendTo (
  SOCKET s,
  LPWSABUF lpBuffers,
  DWORD dwBufferCount,
  LPDWORD lpNumberOfBytesSent,
  DWORD dwFlags,
  const struct sockaddr FAR * lpTo,
  int iTolen,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  LPWSATHREADID lpThreadId,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
lpBuffers
[in] A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length of the buffer. This array must remain valid for the duration of the send operation.
dwBufferCount
[in] The number of WSABUF structures in the lpBuffers array.
lpNumberOfBytesSent
[out] A pointer to the number of bytes sent by this call.
dwFlags
[in] Specifies the way in which the call is made.
lpTo
[in] An optional pointer to the address of the target socket.
iTolen
[in] The size of the address in lpTo.
lpOverlapped
[in] A pointer to a WSAOVERLAPPED structure (ignored for non-overlapped sockets).
lpCompletionRoutine
[in] A pointer to the completion routine called when the send operation has been completed (ignored for non-overlapped sockets).
lpThreadId
[in] A pointer to a WSATHREADID structure to be used by the provider in a subsequent call to WPUQueueApc. The provider should store the referenced WSATHREADID structure (not the pointer to same) until after the WPUQueueApc function returns.
lpErrno
[out] A pointer to the error code.

Remarks

WSPSendTo is normally used on a connectionless socket specified by s to send a datagram contained in one or more buffers to a specific peer socket identified by the lpTo parameter. Even if the connectionless socket has been previously connected to a specific address with the connect function, lpTo overrides the destination address for that particular datagram only. On a connection-oriented socket, the lpTo and iToLen parameters are ignored; in this case the WSPSendTo function is equivalent to WSPSend.

For overlapped sockets (created using WSPSocket with flag WSA_FLAG_OVERLAPPED) this will occur using overlapped I/O, unless both lpOverlapped and lpCompletionRoutine are NULL in which case the socket is treated as a nonoverlapped socket. A completion indication will occur (invocation of the completion routine or setting of an event object) when the supplied buffer(s) have been consumed by the transport. If the operation does not complete immediately, the final completion status is retrieved through the completion routine or WSPGetOverlappedResult.

For nonoverlapped sockets, the parameters lpOverlapped, lpCompletionRoutine, and lpThreadId are ignored and WSPSendTo adopts the regular synchronous semantics. Data is copied from the supplied buffer(s) into the transport's buffer. If the socket is nonblocking and stream oriented, and there is not sufficient space in the transport's buffer, WSPSendTo will return with only part of the Windows Sockets SPI client's buffers having been consumed. Given the same buffer situation and a blocking socket, WSPSendTo will block until all of the Windows Sockets SPI client's buffer contents have been consumed.

The array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation completes in an overlapped manner, it is the service provider's responsibility to capture these WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays.

For message-oriented sockets, care must be taken not to exceed the maximum message size of the underlying transport, which can be obtained by getting the value of socket option SO_MAX_MSG_SIZE. If the data is too long to pass atomically through the underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.

Note that the successful completion of a WSPSendTo does not indicate that the data was successfully delivered.

iFlags can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter. The latter is constructed by OR-ing any of the following values:

Value | Meaning
MSG_DONTROUTE | Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
MSG_OOB | Send out-of-band data (stream-style socket such as SOCK_STREAM only).
MSG_PARTIAL | Specifies that lpBuffers only contains a partial message. Note that the error code WSAEOPNOTSUPP will be returned by transports which do not support partial message transmissions.

Overlapped socket I/O

If an overlapped operation completes immediately, WSPSendTo returns a value of zero and the lpNumberOfBytesSent parameter is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later, WSPSendTo returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent is not updated. When the overlapped operation completes the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSPGetOverlappedResult.

Providers must allow this function to be called from within the completion routine of a previous WSPRecv, WSPRecvFrom, WSPSend or WSPSendTo function. However, for a given socket, I/O completion routines cannot be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate overlapped structure. The WSAOVERLAPPED structure has the following form:

typedef struct _WSAOVERLAPPED {
    DWORD       Internal;        // reserved
    DWORD       InternalHigh;    // reserved
    DWORD       Offset;          // reserved
    DWORD       OffsetHigh;      // reserved
    WSAEVENT    hEvent;
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;

If the lpCompletionRoutine parameter is NULL, the service provider signals the hEvent field of lpOverlapped when the overlapped operation completes if it contains a valid event object handle. Windows Sockets SPI clients can use WSPGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be used by the Windows Sockets SPI client to pass context information to the completion routine. A client that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped IO request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent field is undefined, and attempting to wait on the hEvent field would produce unpredictable results.

It is the service provider's responsibility to arrange for invocation of the client-specified completion routine when the overlapped operation completes. Since the completion routine must be executed in the context of the same thread that initiated the overlapped operation, it cannot be invoked directly from the service provider. The WS2_32.DLL offers an asynchronous procedure call (APC) mechanism to facilitate invocation of completion routines.

A service provider arranges for a function to be executed in the proper thread by calling WPUQueueApc. This function can be called from any process and thread context, even a context different from the thread and process that was used to initiate the overlapped operation.

WPUQueueApc takes as input parameters a pointer to a WSATHREADID structure (supplied to the provider through the lpThreadId input parameter), a pointer to an APC function to be invoked, and a 32-bit context value that is subsequently passed to the APC function. Because only a single 32-bit context value is available, the APC function cannot itself be the client-specified completion routine. The service provider must instead supply a pointer to its own APC function which uses the supplied context value to access the needed result information for the overlapped operation, and then invokes the client-specified completion routine.

The prototype for the client-supplied completion routine is as follows:

void CALLBACK CompletionRoutine (
 IN    DWORD dwError,
 IN    DWORD cbTransferred,
 IN    LPWSAOVERLAPPED lpOverlapped,
 IN    DWORD dwFlags
);

CompletionRoutine is a placeholder for a client supplied function name. dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. cbTransferred specifies the number of bytes sent. No flag values are currently defined and the dwFlags value will be zero. This function does not return a value.

The completion routines can be called in any order, though not necessarily in the same order that the overlapped operations are completed. However, the service provider guarantees to the client that posted buffers are sent in the same order they are supplied.

Return Values

If no error occurs and the receive operation has completed immediately, WSPSendTo returns zero. Note that in this case the completion routine, if specified, will have already been queued. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno. The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that no overlapped operation was initiated and no completion indication will occur.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEACCES | The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINTR | The (blocking) call was canceled through WSPCancelBlockingCall.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAEFAULT | The lpBuffers or lpTo parameters are not part of the user address space, or the lpTo argument is too small.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOBUFS | The Windows Sockets provider reports a buffer deadlock.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only)
WSAENOTSOCK | The descriptor is not a socket.
WSAEOPNOTSUPP | MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, MSG_PARTIAL is not supported, or the socket is unidirectional and supports only receive operations.
WSAESHUTDOWN | The socket has been shut down; it is not possible to WSPSendTo on a socket after WSPShutdown has been invoked with how set to SD_SEND or SD_BOTH.
WSAEWOULDBLOCK | Overlapped sockets: There are too many outstanding overlapped I/O requests. Non-overlapped sockets: The socket is marked as nonblocking and the send operation cannot be completed immediately.
WSAEMSGSIZE | The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
WSAEINVAL | The socket has not been bound with WSPBind, or the socket is not created with the overlapped flag.
WSAECONNABORTED | The virtual circuit was terminated due to a time-out or other failure.
WSAECONNRESET | The virtual circuit was reset by the remote side.
WSAEADDRNOTAVAIL | The remote address is not a valid address (for example, ADDR_ANY).
WSAEAFNOSUPPORT | Addresses in the specified family cannot be used with this socket.
WSAEDESTADDRREQ | A destination address is required.
WSAENETUNREACH | The network cannot be reached from this host at this time.
WSA_OPERATION_ABORTED | The overlapped operation has been canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSPIoctl.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPSocket, WSPGetOverlappedResult, WPUQueueApc


WSPSetSockOpt

The WSPSetSockOpt function sets a socket option.

int WSPSetSockOpt (
  SOCKET s,
  int level,
  int optname,
  const char FAR * optval,
  int optlen,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
level
[in] The level at which the option is defined; the supported levels include SOL_SOCKET. (See annex for more protocol-specific levels.)
optname
[in] The socket option for which the value is to be set.
optval
[in] A pointer to the buffer in which the value for the requested option is supplied.
optlen
[in] The size of the optval buffer.
lpErrno
[out] A pointer to the error code.

Remarks

WSPSetSockOpt sets the current value for a socket option associated with a socket of any type, in any state. Although options can exist at multiple protocol levels, they are always present at the uppermost "socket'' level. Options affect socket operations, such as whether broadcast messages can be sent on the socket.

There are two types of socket options: Boolean options that enable or disable a feature or behavior, and options which require an integer value or structure. To enable a Boolean option, optval points to a nonzero integer. To disable the option optval points to an integer equal to zero. optlen should be equal to sizeof(int) for Boolean options. For other options, optval points to the an integer or structure that contains the desired value for the option, and optlen is the length of the integer or structure.

level = SOL_SOCKET

Value | Type | Meaning
SO_BROADCAST | BOOL | Allow transmission of broadcast messages on the socket.
SO_DEBUG | BOOL | Record debugging information.
SO_DONTLINGER | BOOL | Reserved for future use with socket groups: Do not block close waiting for unsent data to be sent. Setting this option is equivalent to setting SO_LINGER with l_onoff set to zero.
SO_DONTROUTE | BOOL | Do not route: send directly to interface.
SO_GROUP_PRIORITY | int | Specify the relative priority to be established for sockets that are part of a socket group.
SO_KEEPALIVE | BOOL | Send keepalives.
SO_LINGER | struct linger | Linger on close if unsent data is present.
SO_OOBINLINE | BOOL | Receive out-of-band data in the normal data stream.
SO_RCVBUF | int | Specify the total per-socket buffer space reserved for receives. This is unrelated to SO_MAX_MSG_SIZE or the size of a TCP window.
SO_REUSEADDR | BOOL | Allow the socket to be bound to an address which is already in use. (See bind.)
SO_SNDBUF | int | Specify the total per-socket buffer space reserved for sends. This is unrelated to SO_MAX_MSG_SIZE or the size of a TCP window.
PVD_CONFIG | Service Provider Dependent | This object stores the configuration information for the service provider associated with socket s. The exact format of this data structure is service provider specific.

Calling WSPGetSockOpt with an unsupported option will result in an error code of WSAENOPROTOOPT being returned in lpErrno.

SO_DEBUG
Windows Sockets service providers are encouraged (but not required) to supply output debug information if the SO_DEBUG option is set by a Windows Sockets SPI client. The mechanism for generating the debug information and the form it takes are beyond the scope of this specification.
SO_GROUP_PRIORITY
Reserved for future use with socket groups: Group priority indicates the priority of the specified socket relative to other sockets within the socket group. Values are non-negative integers, with zero corresponding to the highest priority. Priority values represent a hint to the service provider about how potentially scarce resources should be allocated. For example, whenever two or more sockets are both ready to transmit data, the highest priority socket (lowest value for SO_GROUP_PRIORITY) should be serviced first, with the remainder serviced in turn according to their relative priorities.

The WSAENOPROTOOPT error is indicated for non group sockets or for service providers which do not support group sockets.

SO_KEEPALIVE
A Windows Sockets SPI client can request that a TCP/IP provider enable the use of "keep-alive" packets on TCP connections by turning on the SO_KEEPALIVE socket option. A Windows Sockets provider need not support the use of keep-alives: if it does, the precise semantics are implementation-specific but should conform to section 4.2.3.6 of RFC 1122: Requirements for Internet Hosts — Communication Layers. If a connection is dropped as the result of "keep-alives" the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN.
SO_LINGER
SO_LINGER controls the action taken when unsent data is queued on a socket and a WSPCloseSocket is performed. See WSPCloseSocket for a description of the way in which the SO_LINGER settings affect the semantics of WSPCloseSocket. The Windows Sockets SPI client sets the desired behavior by creating a struct linger (pointed to by the optval argument) with the following elements:
struct linger {
    u_short    l_onoff;
    u_short    l_linger;
}

To enable SO_LINGER, a Windows Sockets SPI client should set l_onoff to a nonzero value, set l_linger to zero or the desired time-out (in seconds), and call WSPSetSockOpt. To enable SO_DONTLINGER (that is, disable SO_LINGER) l_onoff should be set to zero and WSPSetSockOpt should be called. Note that enabling SO_LINGER with a nonzero time-out on a nonblocking socket is not recommended (see section 4.1.7. WSPCloseSocket for details).

Enabling SO_LINGER also disables SO_DONTLINGER, and vice versa. Note that if SO_DONTLINGER is DISABLED (that is, SO_LINGER is ENABLED) then no time-out value is specified. In this case, the time-out used is implementation dependent. If a previous time-out has been established for a socket (by enabling SO_LINGER), then this time-out value should be reinstated by the service provider.

SO_REUSEADDR
By default, a socket cannot be bound (see WSPBind) to a local address which is already in use. On occasion, however, it may be desirable to "re-use" an address in this way. Since every connection is uniquely identified by the combination of local and remote addresses, there is no problem with having two sockets bound to the same local address as long as the remote addresses are different. To inform the Windows Sockets provider that a WSPBind on a socket should be allowed to bind to a local address that is already in use by another socket, the Windows Sockets SPI client should set the SO_REUSEADDR socket option for the socket before issuing the WSPBind. Note that the option is interpreted only at the time of the WSPBind: it is therefore unnecessary (but harmless) to set the option on a socket which is not to be bound to an existing address, and setting or resetting the option after the WSPBind has no effect on this or any other socket.
SO_SNDBUF
When a Windows Sockets implementation supports the SO_RCVBUF and SO_SNDBUF options, a Windows Sockets SPI client can request different buffer sizes (larger or smaller). The call can succeed even though the service provider did not make available the entire amount requested. A Windows Sockets SPI client must call WSPGetSockOpt with the same option to check the buffer size actually provided.
PVD_CONFIG
This object stores the configuration information for the service provider associated with socket s. The exact format of this data structure is service provider specific.

Return Values

If no error occurs, WSPSetSockOpt returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEFAULT | optval is not in a valid part of the process address space or optlen argument is too small.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAEINVAL | level is not valid, or the information in optval is not valid.
WSAENETRESET | The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress.
WSAENOPROTOOPT | The option is unknown or unsupported for the specified provider.
WSAENOTCONN | Connection has been reset when SO_KEEPALIVE is set.
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPBind, WSPGetSockOpt, WSPIoctl, WSPSocket, WSPEventSelect


WSPShutdown

The WSPShutdown function disables sends and/or receives on a socket.

int WSPShutdown (
  SOCKET s,
  int how,
  LPINT lpErrno
);

Parameters

s
[in] A descriptor identifying a socket.
how
[in] A flag that describes what types of operation will no longer be allowed.
lpErrno
[out] A pointer to the error code.

Remarks

WSPShutdown is used on all types of sockets to disable reception, transmission, or both.

If how is SD_RECEIVE, subsequent receives on the socket will be disallowed. This has no effect on the lower protocol layers. For TCP sockets, if there is still data queued on the socket waiting to be received, or data arrives subsequently, the connection is reset, since the data cannot be delivered to the user. For UDP sockets, incoming datagrams are accepted and queued. In no case will an ICMP error packet be generated.

If how is SD_SEND, subsequent sends on the socket are disallowed. For TCP sockets, a FIN will be sent. Setting how to SD_BOTH disables both sends and receives as described above.

Note that WSPShutdown does not close the socket, and resources attached to the socket will not be freed until WSPCloseSocket is invoked.

Comments

WSPShutdown does not block regardless of the SO_LINGER setting on the socket. A Windows Sockets SPI client should not rely on being able to re-use a socket after it has been shut down. In particular, a Windows Sockets service provider is not required to support the use of WSPConnect on such a socket.

Return Values

If no error occurs, WSPShutdown returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEINVAL | how is not valid, or is not consistent with the socket type. For example, SD_SEND is used with a UNI_RECV socket type.
WSAEINPROGRESS | The function is invoked when a callback is in progress.
WSAENOTCONN | The socket is not connected (connection-oriented sockets only).
WSAENOTSOCK | The descriptor is not a socket.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPConnect, WSPSocket


WSPSocket

The WSPSocket function creates a socket, optionally creates and/or joins a socket group.

SOCKET WSPSocket (
  int af,
  int type,
  int protocol,
  LPWSAPROTOCOL_INFOW lpProtocolInfo,
  GROUP g,
  DWORD dwFlags,
  LPINT lpErrno
);

Parameters

af
[in] An address family specification.
type
[in] A type specification for the new socket.
protocol
[in] A particular protocol to be used with the socket which is specific to the indicated address family.
lpProtocolInfo
[in] A pointer to a WSAPROTOCOL_INFOW structure that defines the characteristics of the socket to be created.
g
[in] Reserved for future use with socket groups: The identifier of the socket group which the new socket is to join.
dwFlags
The socket attribute specification.
lpErrno
[out] A pointer to the error code.

Remarks

WSPSocket causes a socket descriptor and any related resources to be allocated. By default, the created socket will not have the overlapped attribute. Windows Sockets providers are encouraged to be realized as Windows installable file systems, and supply system file handles as socket descriptors. These providers must call WPUModifyIFSHandle prior to returning from this function. For non-file-system Windows Sockets providers, WPUCreateSocketHandle must be used to acquire a unique socket descriptor from the WS2_32.DLL prior to returning from this function. See section Descriptor Allocation for more information.

The values for af, type and protocol are those supplied by the application in the corresponding API functions socket or WSASocket. A service provider is free to ignore or pay attention to any or all of these values as is appropriate for the particular protocol. However, the provider must be willing to accept the value of zero for af and type, since the WS2_32.DLL considers these to be wild card values. Also the value of manifest constant FROM_PROTOCOL_INFO must be accepted for any of af, type and protocol. This value indicates that the Windows Sockets 2 application needs to use the corresponding values from the indicated WSAPROTOCOL_INFOW structure: (iAddressFamily, iSocketType, iProtocol).

Reserved for future use with socket groups: Parameter g is used to indicate the appropriate actions on socket groups:

if g is an existing socket group ID, join the new socket to this group, provided all the requirements set by this group are met; or

if g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket group and have the new socket be the first member; or

if g = SG_CONSTRAINED_GROUP, create a constrained socket group and have the new socket be the first member; or

if g = zero, no group operation is performed

Any set of sockets grouped together must be implemented by a single service provider. For unconstrained groups, any set of sockets can be grouped together. A constrained socket group can consist only of connection-oriented sockets, and requires that connections on all grouped sockets be to the same address on the same host. For newly created socket groups, the new group ID must be available for the Windows Sockets SPI client to retrieve by calling WSPGetSockOpt with option SO_GROUP_ID. A socket group and its associated ID remain valid until the last socket belonging to this socket group is closed. Socket group IDs are unique across all processes for a given service provider.

The dwFlags parameter can be used to specify the attributes of the socket by OR-ing any of the following Flags:

Flag | Meaning
WSA_FLAG_OVERLAPPED | This flag causes an overlapped socket to be created. Overlapped sockets can utilize WSPSend, WSPSendTo, WSPRecv, WSPRecvFrom and WSPIoctl for overlapped I/O operations, which allows multiple operations to be initiated and in progress simultaneously. All functions that allow overlapped operation also support non-overlapped usage on an overlapped socket if the values for parameters related to overlapped operation are NULL.
WSA_FLAG_MULTIPOINT_C_ROOT | Indicates that the socket created will be a c_root in a multipoint session. Only allowed if a rooted control plane is indicated in the protocol's WSAPROTOCOL_INFOW structure.
WSA_FLAG_MULTIPOINT_C_LEAF | Indicates that the socket created will be a c_leaf in a multicast session. Only allowed if XP1_SUPPORT_MULTIPOINT is indicated in the protocol's WSAPROTOCOL_INFOW structure.
WSA_FLAG_MULTIPOINT_D_ROOT | Indicates that the socket created will be a d_root in a multipoint session. Only allowed if a rooted data plane is indicated in the protocol's WSAPROTOCOL_INFOW structure.
WSA_FLAG_MULTIPOINT_D_LEAF | Indicates that the socket created will be a d_leaf in a multipoint session. Only allowed if XP1_SUPPORT_MULTIPOINT is indicated in the protocol's WSAPROTOCOL_INFOW structure.

Important For multipoint sockets, exactly one of WSA_FLAG_MULTIPOINT_C_ROOT or WSA_FLAG_MULTIPOINT_C_LEAF must be specified, and exactly one of WSA_FLAG_MULTIPOINT_D_ROOT or WSA_FLAG_MULTIPOINT_D_LEAF must be specified. Refer to SPI: Protocol-Independent Multicast and Multipoint for additional information.

Connection-oriented sockets such as SOCK_STREAM provide full-duplex connections, and must be in a connected state before any data can be sent or received on them. A connection to another socket is created with a WSPConnect call. Once connected, data can be transferred using WSPSend and WSPRecv calls. When a session has been completed, a WSPCloseSocket must be performed.

The communications protocols used to implement a reliable, connection-oriented socket ensure that data is not lost or duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT.

Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using WSPSendTo and WSPRecvFrom. If such a socket is WSPConnected to a specific peer, datagrams can be sent to that peer using WSPSend and can be received from (only) this peer using WSPRecv.

Support for sockets with type SOCK RAW is not required but service providers are encouraged to support raw sockets whenever it makes sense to do so.

Shared Sockets
When a special WSAPROTOCOL_INFOW structure (obtained through the WSPDuplicateSocket function and used to create additional descriptors for a shared socket) is passed as an input parameter to WSPSocket, the g and dwFlags parameters are ignored.

Layered Service Provider considerations

A layered service provider supplies an implementation of this function, but it is also a client of this function if and when it calls WSPSocket of the next layer in the protocol chain. Some special considerations apply to this function's lpProtocolInfo parameter as it is propagated down through the layers of the protocol chain.

If the next layer in the protocol chain is another layer then when the next layer's WSPSocket is called, this layer must pass to the next layer a lpProtocolInfo that references the same unmodified WSAPROTOCOL_INFOW structure with the same unmodified chain information. However, if the next layer is the base protocol (that is, the last element in the chain), this layer performs a substitution when calling the base provider's WSPSocket. In this case, the base provider's WSAPROTOCOL_INFOW structure should be referenced by the lpProtocolInfo parameter.

One vital benefit of this policy is that base service providers do not have to be aware of protocol chains.

This same propagation policy applies when propagating a WSAPROTOCOL_INFOW structure through a layered sequence of other functions such as WSPAddressToString, WSPDuplicateSocket, WSPStartup, or WSPStringToAddress.

Return Values

If no error occurs, WSPSocket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code is available in lpErrno.

Error Codes

WSAENETDOWN | The network subsystem has failed.
WSAEAFNOSUPPORT | The specified address family is not supported.
WSAEINPROGRESS | A blocking Windows Sockets call is in progress, or the service provider is still processing a callback function.
WSAEMFILE | No more socket descriptors are available.
WSAENOBUFS | No buffer space is available. The socket cannot be created.
WSAEPROTONOSUPPORT | The specified protocol is not supported.
WSAEPROTOTYPE | The specified protocol is the wrong type for this socket.
WSAESOCKTNOSUPPORT | The specified socket type is not supported in this address family.
WSAEINVAL | The parameter g specified is not valid.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPAccept, WSPBind, WSPConnect, WSPGetSockName, WSPGetSockOpt, WSPSetSockOpt, WSPListen, WSPRecv, WSPRecvFrom, WSPSend, WSPSendTo, WSPShutdown, WSPIoctl, WPUCreateSocketHandle


WSPStartup

The WSPStartup function initiates use of a Windows Sockets service provider by a client.

int WSPStartup (
  WORD wVersionRequested,
  LPWSPDATAW lpWSPData,
  LPWSAPROTOCOL_INFOW lpProtocolInfo,
  WSPUPCALLTABLE UpcallTable,
  LPWSPPROC_TABLE lpProcTable
);

Parameters

wVersionRequested
[in] The highest version of Windows Sockets SPI support that the caller can use. The high order byte specifies the minor version (revision) number; the low-order byte specifies the major version number.
lpWSPData
[out] A pointer to the WSPDATA data structure that is to receive details of the Windows Sockets service provider.
lpProtocolInfo
[in] A pointer to a WSAPROTOCOL_INFOW structure that defines the characteristics of the desired protocol. This is especially useful when a single provider DLL is capable of instantiating multiple different service providers..
UpcallTable
[in] The WS2_32.DLL's upcall dispatch table.
lpProcTable
[out] A pointer to the table of SPI function pointers.

Remarks

This function must be the first Windows Sockets SPI function called by a Windows Sockets SPI client on a per-process basis. It allows the client to specify the version of Windows Sockets SPI required and to provide its upcall dispatch table. All upcalls (that is, functions prefixed with WPU) made by the Windows Sockets service provider are invoked through the client's upcall dispatch table. This function also allows the client to retrieve details of the specific Windows Sockets service provider implementation. The Windows Sockets SPI client can only issue further Windows Sockets SPI functions after a successful WSPStartup invocation. A table of pointers to the rest of the SPI functions is retrieved through the lpProcTable parameter.

In order to support future versions of the Windows Sockets SPI and the WS2_32.DLL which may have functionality differences from the current Windows Sockets SPI, a negotiation takes place in WSPStartup. The caller of WSPStartup (either the WS2_32.DLL or a layered protocol) and the Windows Sockets service provider indicate to each other the highest version that they can support, and each confirms that the other's highest version is acceptable. Upon entry to WSPStartup, the Windows Sockets service provider examines the version requested by the client. If this version is equal to or higher than the lowest version supported by the service provider, the call succeeds and the service provider returns in wHighVersion the highest version it supports and in wVersion the minimum of its high version and wVersionRequested. The Windows Sockets service provider then assumes that the Windows Sockets SPI client will use wVersion. If the wVersion field of the WSPDATA structure is unacceptable to the caller, it should call WSPCleanup and either search for another Windows Sockets service provider or fail to initialize.

This negotiation allows both a Windows Sockets service provider and a Windows Sockets SPI client to support a range of Windows Sockets versions. A client can successfully utilize a Windows Sockets service provider if there is any overlap in the version ranges. The following chart gives examples of how WSPStartup works in conjunction with different WS2_32.DLL and Windows Sockets service provider (SP) versions:

DLL Versions | SP Versions | wVersion Requested | wVersion | wHigh Version | End Result
1.1 | 1.1 | 1.1 | 1.1 | 1.1 | use 1.1
1.0 1.1 | 1.0 | 1.1 | 1.0 | 1.0 | use 1.0
1.0 | 1.0 1.1 | 1.0 | 1.0 | 1.1 | use 1.0
1.1 | 1.0 1.1 | 1.1 | 1.1 | 1.1 | use 1.1
1.1 | 1.0 | 1.1 | 1.0 | 1.0 | DLL fails
1.0 | 1.1 | 1.0 | --- | --- | WSAVERNOTSUPPORTED
1.0 1.1 | 1.0 1.1 | 1.1 | 1.1 | 1.1 | use 1.1
1.1 2.0 | 1.1 | 2.0 | 1.1 | 1.1 | use 1.1
2.0 | 2.0 | 2.0 | 2.0 | 2.0 | use 2.0

The following code fragment demonstrates how a Windows Sockets SPI client which supports only version 2 of Windows Sockets SPI makes a WSPStartup call:

WORD wVersionRequested;
WSPDATA WSPData;

int err;

WSPUPCALLTABLE upcallTable =
{
    /* initialize upcallTable with function pointers */
};

LPWSPPROC_TABLE lpProcTable =
{
    /* allocate memory for the ProcTable */
};

wVersionRequested = MAKEWORD( 2, 2 );

err = WSPStartup( wVersionRequested, &WSPData, lpProtocolBuffer, upcallTable, lpProcTable );
if ( err != 0 ) {
    /* Tell the user that we could not find a useable */
    /* Windows Sockets service provider.                     */
    return;
}

/* Confirm that the Windows Sockets service provider supports 2.2.*/
/* Note that if the service provider supports versions */
/* greater than 2.2 in addition to 2.2, it will still */
/* return 2.2 in wVersion since that is the version we  */
/* requested.                                           */

if ( LOBYTE( WSPData.wVersion ) != 2 ||
         HIBYTE( WSPData.wVersion ) != 2 ) {
    /* Tell the user that we could not find a useable */
    /* Windows Sockets service provider.                     */
    WSPCleanup( );
    return;
}

/* The Windows Sockets service provider is acceptable. Proceed. */

And this code fragment demonstrates how a Windows Sockets service provider which supports only version 2 performs the WSPStartup negotiation:

/* Make sure that the version requested is >= 2.2.  */
/* The low byte is the major version and the high   */
/* byte is the minor version.                       */

if ( LOBYTE( wVersionRequested ) < 2) ||
    ((LOBYTE( wVersionRequested ) == 2) &&
     (HIBYTE( wVersionRequested ) < 2))) {
    return WSAVERNOTSUPPORTED;
}

/* Since we only support 2.2, set both wVersion and  */
/* wHighVersion to 2.2.                              */

lpWSPData->wVersion = MAKEWORD( 2, 2 );
lpWSPData->wHighVersion = MAKEWORD( 2, 2 );

Once the Windows Sockets SPI client has made a successful WSPStartup call, it can proceed to make other Windows Sockets SPI calls as needed. When it has finished using the services of the Windows Sockets service provider, the client must call WSPCleanup in order to allow the Windows Sockets service provider to free any resources allocated for the client.

Details of how Windows Sockets service provider information is encoded in the WSPData structure is as follows:

typedef struct WSPData {
    WORD        wVersion;
    WORD        wHighVersion;
    WCHAR       szDescription[WSPDESCRIPTION_LEN+1];
} WSPDATA, FAR * LPWSPDATA;

The members of this structure are:

Element | Usage
wVersion | The version of the Windows Sockets SPI specification that the Windows Sockets service provider expects the caller to use.
wHighVersion | The highest version of the Windows Sockets SPI specification that this service provider can support (also encoded as above). Normally this will be the same as wVersion.
szDescription | A null-terminated Unicode string into which the Windows Sockets provider copies a description of itself. The text (up to 256 characters in length) can contain any characters except control and formatting characters: the most likely use that a SPI client will put this to is to display it (possibly truncated) in a status message.

A Windows Sockets SPI client can call WSPStartup more than once if it needs to obtain the WSPData structure information more than once. On each such call the client can specify any version number supported by the provider.

There must be one WSPCleanup call corresponding to every successful WSPStartup call to allow third-party DLLs to make use of a Windows Sockets provider. This means, for example, that if WSPStartup is called three times, the corresponding call to WSPCleanup must occur three times. The first two calls to WSPCleanup do nothing except decrement an internal counter; the final WSPCleanup call does all necessary resource deallocation.

This function (and most other service provider functions) can be invoked in a thread that started out as a 16-bit process if the client is a 16-bit Windows Sockets 1.1 client. One important limitation of 16-bit processes is that a 16-bit process cannot create threads. This is significant to service provider implementers that plan to use an internal service thread as part of the implementation.

Fortunately, there are usually only two areas where the desire for a service thread is strong: (1) in the implementation of overlapped I/O completion, and (2) in the implementation of WSPEventSelect. Both of these areas are only accessible through new Windows Sockets 2 functions, which can only be invoked by 32-bit processes. A service thread can be safely used if several design rules are carefully followed: (1) Use a service thread only for functionality that is unavailable to 16-bit Windows Sockets 1.1 clients, and (2) create the service thread only on demand.

Several other cautions apply to the use of internal service threads. First, threads generally carry some performance penalty. Use as few as possible, and avoid thread transitions wherever possible. Second, your code should always check for errors in creating threads and fail gracefully and informatively (for example, with WSAEOPNOTSUPP) in case some execution event you did not expect results in a 16-bit process executing a code path that needs threads.

Layered Service Provider Considerations

A layered service provider supplies an implementation of this function, but it is also a client of this function when it calls WSPStartup to initialize the next layer in the protocol chain. The call to the next layer's WSPStartup may happen during the execution of this layer's WSPStartup or it may be delayed and called on demand, such as when WSPSocket is called. In any case, some special considerations apply to this function's lpProtocolInfo parameter as it is propagated down through the layers of the protocol chain.

The layered provider searches the ProtocolChain of the structure referenced by lpProtocolInfo to determine its own location in the chain (by searching for the layer's own catalog entry Id) and the identity of the next element in the chain. If the next element is another layer then when the next layer's WSPStartup is called, this layer must pass to the next layer a lpProtocolInfo that references the same unmodified WSAPROTOCOL_INFOW structure with the same unmodified chain information. However, if the next layer is the base protocol (i.e., the last element in the chain), this layer performs a substitution when calling the base provider's WSPStartup. In this case, the base provider's WSAPROTOCOL_INFOW structure should be referenced by the lpProtocolInfo parameter.

One vital benefit of this policy is that base service providers do not have to be aware of protocol chains.

This same propagation policy applies when propagating a WSAPROTOCOL_INFOW structure through a layered sequence of other functions such as WSPAddressToString, WSPDuplicateSocket, WSPSocket, or WSPStringToAddress.

Return Values

WSPStartup returns zero if successful. Otherwise, it returns one of the error codes listed below.

Error Codes

WSASYSNOTREADY | Indicates that the underlying network subsystem is not ready for network communication.
WSAVERNOTSUPPORTED | The version of Windows Sockets SPI support requested is not provided by this particular Windows Sockets service provider.
WSAEINPROGRESS | A blocking Windows Sockets operation is in progress.
WSAEPROCLIM | Limit on the number of clients supported by the Windows Sockets implementation has been reached.
WSAEFAULT | The lpWSPData or lpProcTable parameter is invalid.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.

See Also

WSPSend, WSPSendTo, WSPCleanup


WSPStringToAddress

The WSPStringToAddress function converts a human-readable numeric string to a socket address structure (SOCKADDR) suitable to passing to Windows Sockets routines which take such a structure.

Any missing components of the address will be defaulted to a reasonable value if possible. For example, a missing port number will default to zero.

int WSPStringToAddress (
  LPWSTR AddressString,
  INT AddressFamily,
  LPWSAPROTOCOL_INFOW lpProtocolInfo,
  LPSOCKADDR lpAddress,
  LPINT lpAddressLength,
  LPINT lpErrno
);

Parameters

AddressString
[in] Points to the zero-terminated human-readable string to convert.
AddressFamily
[in] The address family to which the string belongs, or AF_UNSPEC if it is unknown.
lpProtocolInfo
[in] (required) The provider's WSAPROTOCOL_INFOW structure.
lpAddress
[out] A buffer which is filled with a single SOCKADDR structure.
lpAddressLength
[in/out] The length of the Address buffer. Returns the size of the resultant SOCKADDR structure. If the supplied buffer is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated with the required size in bytes.
lpErrno
[out] A pointer to the error code.

Layered Service Provider Considerations

A layered service provider supplies an implementation of this function, but it is also a client of this function if and when it calls WSPStringToAddress of the next layer in the protocol chain. Some special considerations apply to this function's lpProtocolInfo parameter as it is propagated down through the layers of the protocol chain.

If the next layer in the protocol chain is another layer then when the next layer's WSPStringToAddress is called, this layer must pass to the next layer a lpProtocolInfo that references the same unmodified WSAPROTOCOL_INFOW structure with the same unmodified chain information. However, if the next layer is the base protocol (that is, the last element in the chain), this layer performs a substitution when calling the base provider's WSPStringToAddress. In this case, the base provider's WSAPROTOCOL_INFOW structure should be referenced by the lpProtocolInfo parameter.

One vital benefit of this policy is that base service providers do not have to be aware of protocol chains.

This same propagation policy applies when propagating a WSAPROTOCOL_INFOW structure through a layered sequence of other functions such as WSPAddressToString, WSPDuplicateSocket, WSPStartup, or WSPSocket.

Return Values

If no error occurs, WSPStringToAddress returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error Codes

WSAEFAULT | The specified Address buffer is too small. Pass in a larger buffer.
WSAEINVAL | Unable to translate the string into a SOCKADDR, or the provider was unable to support the indicated address family, or the specified lpProtocolInfo did not refer to a WSAPROTOCOL_INFOW structure supported by the provider.

QuickInfo

Windows NT: Yes
Windows: Yes
Windows CE: Unsupported.
Header: Declared in ws2spi.h.


Legal Information

Windows Sockets Version 2 Provider-Specific Annex

This is a preliminary document and may be changed substantially prior to final commercial release. This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document. Information in this document is subject to change without notice. The entire risk of the use or the results of the use of this document remains with the user. The names of companies, products, people, characters, and/or data mentioned herein are fictitious and are in no way intended to represent any real individual, company, product, or event, unless otherwise noted. Complying with all applicable copyright laws is the responsibility of the user. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Microsoft Corporation.

Portions of this document specify and accompany software that is still in development. Some of the information in this documentation may be inaccurate or may not be an accurate representation of the functionality of final documentation or software. Microsoft assumes no responsibility for any damages that might occur directly or indirectly from these inaccuracies.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

©1997-1998 Microsoft Corporation. All rights reserved.

Microsoft, MS, Win32, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

All other product and company names mentioned herein are the trademarks of their respective owners.


Windows Sockets 2 Protocol-Specific Annex

This document describes the Windows Sockets 2 Protocol-Specific Annex. It primarily consists of information from the Windows Sockets 2 Protocol-Specific Annex specification, but includes additional information as well. The information in this document is not presented in exactly the same way as in the specification.


Welcome to the Windows Sockets 2 Protocol-Specific Annex

Using This Document

Overview of Windows Sockets 2

Microsoft Extensions and Windows Sockets 2


Using This Document

This document provides the on-line material needed to create a Windows Sockets application for the Windows NT®, Windows® 95, and Windows 98 operating systems, using the Microsoft implementation of Windows Sockets 2. It is intended as a reference tool and outlines the functions in the Windows Sockets Protocol-Specific Annex.

You should be familiar with Win32 programming concepts to make the best use of this document. Thus, you may want to refer to other references that provide a more systematic guide to writing Windows Sockets applications.

Note This documentation is intended for application developers. If you are developing a transport or service provider, see the "Service Provider Documentation" installed with the Platform SDK.


Overview of Windows Sockets 2

The Windows Sockets 2 specification is a superset of the widely deployed Windows Sockets 1.1 interface. While maintaining full backward compatibility, it extends the Windows Sockets interface in a number of areas, including providing access to protocols other than TCP/IP. Windows Sockets allows an application to use the familiar socket interface to achieve simultaneous access to any number of installed transport protocols.

While most of these protocols' facilities may be used with standard Windows Sockets 2 interface mechanisms, each supported protocol has certain conventions and behaviors which developers may need to become aware of. Also, individual protocols support special features that do not lend themselves to being treated generically. The purpose of this document is to provide the details necessary for developers to effectively use any of the supported protocols.


Socket Handles for Windows Sockets 2

A socket handle can optionally be a file handle in Windows Sockets 2. It is possible to use socket handles with ReadFile, WriteFile, ReadFileEx, WriteFileEx, DuplicateHandle, and other Win32 functions. Not all transport service providers will support this option. However, for an application to run over the widest possible number of service providers, it should not assume that socket handles are file handles.

Windows Sockets 2 has expanded certain functions that transfer data between sockets using handles. The functions offer advantages specific to sockets for transferring data and include WSARecv, WSASend, and WSADuplicateSocket.


TCP/IP

This section describes TCP/IP functions, data structures, and TCP/IP controls.

  • TCP/IP Introduction
  • TCP/IP Overview
  • TCP/IP Data Structures
  • TCP/IP Controls
  • TCP/IP Function Details


TCP/IP Introduction

This section covers extensions to Windows Sockets 2 that are specific to TCP/IP protocols. It also describes aspects of base Windows Sockets 2 functions that require special consideration or which may exhibit unique behavior when using TCP/IP.

Fast Facts

Protocol Name(s) | TCP, UDP
Description | Provides two transport services over the IP networking layer: UDP for unreliable datagrams, TCP for reliable, connection-oriented byte streams.
Address Family | AF_INET
Header File | WS2TCPIP.H


TCP/IP Overview

The TCP/IP protocol suite form the backbone of the global Internet. The original Windows Sockets specification (version 1.1) addressed only TCP/IP protocols, and still has a few IP-specific peculiarities.

Two basic types of transport services are offered: unreliable datagrams (UDP), and reliable connection-oriented byte streams (TCP). In addition, a raw socket is optionally supported. Raw sockets allow an application to communicate via protocols other than TCP and UDP such as ICMP.


TCP/IP Data Structures

The INTERFACE_INFO structure is used in conjunction with the SIO_GET_INTERFACE_LIST ioctl command. It is defined in Ws2tcpip.h file and is reproduced here.

typedef struct _INTERFACE_INFO
{
    u_long    iiFlags;      /* Type and status of the interface */
    struct sockaddr    iiAddress;        /* Interface address */
    struct sockaddr    iiBroadcastAddress;     /* Broadcast address */
    struct sockaddr    iiNetmask;        /* Network mask */
} INTERFACE_INFO;

Members

iiFlags
A bitmask describing the status of the interface. The following flags are possible:
IFF_UP
The interface is running.
IFF_BROADCAST
The broadcast feature is supported
IFF_LOOPBACK
The loopback interface is running.
IFF_POINTTOPOINT
The interface is using point-to-point link.
IFF_MULTICAST
The multicast feature is supported.
iiAddress
The address of the interface.
iiBroadcastAddress
The broadcast address of the interface or the address of the other side for point-to-point links.
iiNetmask
The netmask used by the interface.


TCP/IP Controls

The following controls are available in all TCP/IP implementations.

  • UNIX Ioctls
  • TCP/IP Socket Options


UNIX Ioctls

The SIOGIFCONF command provided by most UNIX implementations is supported in form of WSAIoctl and WSPIoctl functions with the command SIO_GET_INTERFACE_LIST. This command returns the list of configured interfaces and their parameters. Support of this command is mandatory for Windows Sockets 2 compliant TCP/IP service providers.

The parameter lpvOutBuffer points to the buffer in which the WSAIoctl/WSPIoctl functions stores the information about interfaces. The description of the structure of this appears above. The number of interfaces (number of structures returned in lpvOutBuffer) can be determined based on the actual length of the output buffer returned in lpcbBytesReturned.


TCP/IP Socket Options

The following TCP/IP specific options are defined:

level=IPPROTO_IP

Value | Type | Meaning
IP_OPTIONS | char FAR * | List of IP options to be inserted into outgoing packets.
IP_TOS | int | Specifies type of service to be used
IP_TTL | int | Specify TTL to be used
IP_HDRINCL | BOOL | If true, application will provide IP header in the packets sent over SOCK_RAW interface, otherwise the header is provided by the service provider.
IP_MULTICAST_IF | struct in_addr FAR * | Select interface for outgoing multicast packets. The optval should point to the address of the interface to be used. If NULL, the default interface is used.
IP_MULTICAST_TTL | int | TTL used for the multicast packets
IP_MULTICAST_LOOP | BOOL | If true, multicast loopback is enabled, otherwise - disabled.
IP_ADD_MEMBERSHIP | struct ip_mreq FAR * | Specify the multicast group to join
IP_DROP_MEMBERSHIP | struct ip_mreq FAR * | Specify the multicast group to leave

level= IPPROTO_UDP

Value | Type | Meaning
UDP_NOCHECKSUM | BOOL | If the option is set, UDP datagrams are sent with the checksum of zero. This option is required. If a service provider does not have a mechanism to disable UDP checksum calculation, it may just store this option without doing any actions.

level= IPPROTO_TCP

Value | Type | Meaning
TCP_EXPEDITED_1122 | BOOL | If set, the Service Provider implements the expedited data as specified in RFC-1222, otherwise the BSD style (default) is used. This option can be set on the connection only once, i.e. once on, this option can not be turned off. This option is not required.

IP_OPTIONS
Specifies IP options to be inserted into outgoing datagrams. Setting the new options overwrites all the previously specified options. Setting optval to zero means removing all the previously specified options. The support of IP_OPTIONS is not required. In order to check if IP_OPTIONS is supported or not, an application should use getsockopt trying to get the current options. If getsockopt fails, the IP_OPTIONS is not supported.
IP_TOS
Changes the default value set by the TCP/IP service provider in the TOS field of IP header in outgoing datagrams. The support of IP_TOS is not required. In order to check if IP_TOS is supported or not, an application should use getsockopt trying to get the current options. If getsockopt fails, the IP_TOS is not supported.
IP_TTL
Change the default value set by the TCP/IP service provider in the TTL field of IP header in outgoing datagrams. The support of IP_TTL is not required. In order to check if IP_TTL is supported or not, an application should use getsockopt trying to get the current options. If getsockopt fails, the IP_TTL is not supported.
IP_HDRINCL
By default TCP/IP service provider forms the IP header for the outcoming datagrams. Some applications, however, may wish to provide their own IP header. Such applications should set IP_HDRINCL option into true and then supply a completed IP header at the front of each outgoing datagram. The only modification TCP/IP service provider may do to the supplied IP header is setting the ID field if the value supplied by the application is 0. The IP_HDRINCL option is applied only to the SOCK_RAW type of protocol. If a TCP/IP service provider supports SOCK_RAW protocol, it should also support IP_HDRINCL option.
IP_MULTICAST_IF
Information supplied at a later release.
IP_MULTICAST_TTL
Information supplied at a later release.
IP_MULTICAST_LOOP
Information supplied at a later release.
IP_ADD_MEMBERSHIP
Information supplied at a later release.
IP_DROP_MEMBERSHIP
Support of these options is required if a protocol supports multicast. This will be indicated in the WSAPROTOCOL_INFO structure returned by WSAEnumProtocols as follows:

XPI_SUPPORTS_MULTIPOINT = 1

XP1_MULTIPOINT_CONTROL_PLANE = 0

XP1_MULTIPOINT_DATA_PLANE = 0


TCP/IP Function Details

This section presents general information about TCP/IP function details for Multicast, Raw sockets, and Ipv6 support.

  • Multicast
  • TCP/IP Raw Sockets
  • IPv6 Support
  • Text representation of IPv6 addresses


Multicast

Generic Windows Sockets multipoint functions support IP multicast. However, the TCP/IP transport providers who support multicast must also provide 'BSD-style' multicast support by supporting the corresponding multicast options. This will simplify the porting of existing multicast applications to Windows Sockets 2.


TCP/IP Raw Sockets

The TCP/IP service providers may support SOCK_RAW type of the socket. There are two types of such sockets: the first one assumes known protocol type as written in IP header, the second one allows any protocol number. An example of the first type of socket is ICMP, an example of the second type would be an experimental protocol which is not supported by the service provider.

If TCP/IP service provider supports SOCK_RAW sockets for the AF_INET family, the corresponding protocol(s) should be included in the list returned by WSAEnumProtocols. The ipProtocol field of the WSAPROTOCOL_INFO structure may be set to 0 if the service provider allows an application to specify any value for the protocol parameter for the socket, WSASocket and WSPSocket functions.

Note An application may not specify zero (0) as the protocol parameter for the socket, WSASocket, and WSPSocket functions if SOCK_RAW sockets are used.

The following rules are applied to the operations over SOCK_RAW sockets:

  • when an application sends a datagram it may or may not include the IP header at the front of the outgoing datagrams depending on the IP_HDRINCL option set for the socket.
  • an application always gets the IP header at front of each received datagram regardless of the IP_HDRINCL option.
  • received datagrams are copied into all SOCK_RAW sockets which satisfy the following conditions:
    • the protocol number specified for the socket should match the protocol number in the IP header of the received datagram;
    • if a local IP address is defined for the socket, it should correspond to the destination address as specified in the IP header of the received datagram. An application may specify the local IP address by calling bind functions. If no local IP address is specified for the socket, the datagrams are copied into the socket regardless of the destination IP address in the IP header of the received datagram;
    • if a foreign address is defined for the socket, it should correspond to the source address as specified in IP header of the received datagram. An application may specify the foreign IP address by calling connect functions. If no foreign IP address is specified for the socket, the datagrams are copied into the socket regardless of the source IP address in the IP header of the received datagram.

It is important to understand that SOCK_RAW sockets may get many 'unexpected' datagrams. For example, a PING program may use SOCK_RAW socket to send ICMP echo requests. While the application is expecting ICMP echo responses, all the other ICMP messages (like ICMP HOST_UNREACHABLE) may be delivered to this application also. Moreover, if several SOCK_RAW sockets are open on a machine at the same time, the same datagrams may be delivered to all the open sockets. An application must have a mechanism to recognize 'its' datagram and to ignore all the others. Such mechanism may include inspecting the received IP header, using unique IDs in the ICMP header (ProcessID, for example), etc.


IPv6 Support

If TCP/IP service provider supports IPv6 addressing, it must install itself twice: once for IPv4 and once for IPv6 address family. So, WSAEnumProtocols will return two WSAPROTOCOL_INFO structures for each of the supported socket types (SOCK_STREAM, SOCK_DGRAM, SOCK_RAW). The iAddressFamily must by set to AF_INET for IPv4 addressing, and to AF_INET6 for IPv6 addressing.

The IPv6 addresses are described in the following structures:

struct sockaddr_in6 {
      short             sin6_family;     /* AF_INET6 */
      u_short           sin6_port;       /* Transport level port number */
      u_long            sin6_flowinfo;    /* IPv6 flow information */
      struct in_addr6   sin6_addr; /* IPv6 address */
   };

    struct    in_addr6 {
        u_char    s6_addr[16];    /* IPv6 address */
    };

If an application uses Windows Sockets 1.1 functions and wants to use IPv6 addresses, it may continue to use all the old functions which take struct sockaddr as one of the parameters (bind, connect, sendto, recvfrom, accept, etc.). The only change that is required is to use struct sockaddr_in6 instead of struct sockaddr. However, all the name resolution functions (gethostbyname, gethostbyaddr, etc.) and address conversion functions (inet_addr, inet_ntoa) can not be reused because they assume an IP address of 4 bytes in length. An application which wants to do name resolution and address conversion for IPv6 addresses must use Windows Sockets 2 specific functions (WSAStringToAddress, WSAAddressToString, etc.)

The multicast for IPv6 has to be specified in more details in a later version.


Text representation of IPv6 addresses

This section is copied from the "IP Version 6 Addressing Architecture" by R.Hinden and S. Deering <draft-ietf-ipngwg-addr-arch-03.txt>

There are three conventional forms for representing IPv6 addresses as text strings:

  1. The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the hexadecimal values of the eight 16-bit pieces of the address.

    Examples:

    FEDC:BA98:7654:3210:FEDC:BA98:7654:3210

    1080:0:0:0:8:800:200C:417A

    Note It is not necessary to write the leading zeros in an individual field, but there must be at least one numeral in every field (except for the case described in 2.).

  2. Due to the method of allocating certain styles of IPv6 addresses, it will be common for addresses to contain long strings of zero bits. In order to make writing addresses containing zero bits easier a special syntax is available to compress the zeros. The use of two "::" indicate multiple groups of 16-bits of zeros.

    For example the multicast address:

    FF01:0:0:0:0:0:0:43

    may be represented as:

    FF01::43

    The "::" can only appear once in an address. The "::" can also be used to compress the leading or trailing zeros in an address.

  3. An alternative form that is sometimes more convenient when dealing with a mixed environment of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values of the six high-order 16-bit pieces of the address, and the 'd's are the decimal values of the four low-order 8-bit pieces of the address (standard IPv4 representation).

    Examples:

    0:0:0:0:0:0:13.1.68.3

    0:0:0:0:0:FFFF:129.144.52.38

    or in compressed form:

    ::13.1.68.3

    ::FFFF:129.144.52.38


TCP/IP Header File

Use the WS2TCPIP.H header file for TCP/IP transactions.


IPX/SPX

This section introduces and provides important specifics for IPX/SPX.

  • IPX/SPX Introduction
  • IPX/SPX Overview
  • IPX/SPX Data Structures
  • IPX/SPX Controls
  • IPX/SPX Function Specifics


IPX/SPX Introduction

This section covers extensions to Windows Sockets 2 that are specific to IPX family of transport protocols. It also describes aspects of base Windows Sockets 2 functions that require special consideration or which may exhibit unique behavior.

Fast Facts

Protocol Name(s) | IPX, SPX
Description | Provides transport services over the IPX networking layer: IPX for unreliable datagrams, SPX for reliable, connection-oriented message streams.
Address Family | AF_IPX
Header File | WSIPX.H


IPX/SPX Overview

This section discusses how to use the Windows Sockets 2 API with the IPX family of protocols. Traditionally, the Windows Sockets 1.x specification has been used with the IP family of protocols such as TCP and UDP. However, with the advent of Windows Sockets 2, the API has been updated to more easily access a wide range of transport and network types. The Windows Sockets 2 API is sufficiently generic that programmers need to know very little about the specifics of the IPX/SPX implementation. However, if you are moving traditional IPX applications to Windows Sockets or desire more knowledge of the IPX/SPX implementation, this appendix is for you. Be aware that IPX networks operate differently than IP networks, and some consideration of this fact will most likely be evident in your code.

IPX/SPX features are defined in the header file wsipx.h.


The AF_IPX Address Family

The IPX address family defines the addressing structure for protocols that use standard IPX socket addressing. For these transports, an endpoint address consists of a network number, node address and socket number.

The network number is an administrative domain and typically names a single Ethernet or token ring segment. The node number is a station's physical address. The combination of net and node form a unique station address which is presumed to be unique in the world. Net/node numbers are represented in ASCII in either block or dashed notation as: '0101a040,00001b498765' or '01-01-a0-40,00-00-1b-49-87-65'. Leading zero's need not be present.

The IPX socket number is a network/transport service number much like a TCP port number and is not to be confused with the Windows Sockets socket descriptor. IPX Socket numbers are global to the end-station and cannot be bound to specific net/node addresses. For instance, if the end-station has two network interface cards, a bound socket can send and receive on both cards. In particular, datagram sockets would receive broadcast datagrams on both cards.

Caution Sockaddr_ipx is 14 bytes long and is shorter than the 16-byte sockaddr reference structure. IPX/SPX implementations may accept the 16 byte length as well as the true length. If you use sockaddr_ipx and a hard coded length of 16 bytes, the implementation may assume that it has access to the two bytes following your structure.

Field | Value
sa_family | Address family AF_IPX in host order.
Sa_netnum | IPX network identifier in network order.
Sa_nodenum | Station node address, flushed right.
Sa_socket | IPX socket number in network order.


The IPX Family of Protocol Identifiers

The protocol parameter in socket and WSASocket is an identifier that establishes a network type and a method for identifying the various transport protocols that run on the network. Unlike IP, IPX does not use a single protocol value for selecting a transport stack. Since there is no network requirement to use a specific value for each transport protocol, we are free to assign them in a manner convenient for Windows Sockets applications. We avoid values 0..255 in order to avoid collisions with the corresponding PF_INET protocol values.

Name | Value | Socket Types | Description
Reserved | 0-255 |  | Reserved for PF_INET protocol values.
NSPROTO_IPX | 1000 - 1255 | SOCK_DGRAM SOCK_RAW | Datagram service for IPX.
NSPROTO_SPX | 1256 | SOCK_STREAM SOCK_SEQPKT | Reliable packet exchange using fixed-sized packets.

Note

When NSPROTO_SPX is specified, the SPX II protocol will automatically be utilized if both endpoints are capable of doing so.


Broadcast to Local Network

A broadcast can be made to the locally attached network by setting sa_netnum to binary 0's and sa_nodenum to binary 1's. This broadcast may be sent to the primary network for the device, or all locally attached networks at the option of the service provider. Broadcasts to the local network are not propagated by routers.


All routes broadcast

A general broadcast through the Internet is achieved by setting the sa_netnum and sa_nodenum fields to binary 1's (-1). The service provider translates this request to a 'type 20 packet', which IPX routers recognize and forward. Your packet will visit all subnets and may be duplicated several times. Receivers must handle several duplicate copies of your datagram.

Use of this broadcast type is very unpopular among network administrators and its use should be extremely limited. Many routers disable this type of broadcast, leaving parts of the subnet invisible to your packet.


Directed broadcast

Generally considered more network-friendly than all-routes broadcast, a directed broadcast limits the broadcast to the local network you specify. Fill sa_netnum with the target network number and sa_nodenum with binary 1's. Routers forward this request to the destination network where it becomes a local broadcast. Intermediate networks do not see this packet as a broadcast.


About Media Packet Size

Media packet size affects the ability of IPX protocols to transfer data across networks and can prove challenging to deal with in a transport-independent manner. IPX does not segment packets, nor does it report when packets are dropped due to size violations. This means that some entity on the end-station must maintain knowledge of the maximum packet size to be used on any given inter-network path. Traditionally, IPX datagram and SPX connection-oriented services have left this burden to the application, while SPXII has used Large Internet Packet negotiation to handle it transparently.

Windows Sockets attempts to set rational packet size limits for its various IPX protocols as stated in the next section. These limits can be viewed and modified by applications via get/set socket options. When determining maximum packet size, the three areas of concern are:

# Media packet size
#  Routable packet size
#  End-station packet size

Media packet size reflects the maximum packet size acceptable on any media the packet transverses to its destination. Packet size varies among differing media such as Ethernet and token ring. The amount of data space within a packet can also vary within a given media, depending on the packet header arrangement. For instance, the effective data size of an Ethernet packet varies depending on whether it is of type Ethernet II, Ethernet 802.2 or Ethernet SNAP.

Routable packet size reflects the maximum packet size an intermediate router is willing to forward. Modern IPX routers are built to route any size datagram as long as it remains within the media size of the sending and receiving network. However, older routers may limit maximum packet size to 576 bytes, including protocol headers.

End-station packet size reflects the size of the listen buffers end-stations have posted to receive incoming packets. Even when the media and router limits allow a packet through, it may be discarded by the end-station if the receiving application has posted a smaller buffer. Many traditional IPX/SPX applications limit receive buffer size such that the data portion must be no larger than 512 or 1024 bytes.


How Packet Size Affects Protocols

Media packet size issues discussed above affect the various PF_IPX protocols differently. A common strategy for handling various router and media size constraints is to use the full media size when the remote station's network number matches the local station and fall back to the minimum packet size otherwise.

NSPROTO_IPX
Provides a datagram service and each datagram must reside within the maximum packet size. Windows Sockets sets the maximum datagram packet size to the local media packet size minus the IPX header. Keep in mind, however, that if the packet is routed, it may hit router restrictions en-route. Make sure your application can fall back to 546 byte datagrams.
NSPROTO_SPX
Provides stream and sequenced-packet services. Windows Sockets IPX/SPX lets data streams and messages span multiple packets, so packet size does not limit the amount of data handled by send and recv. However, the underlying media size must be set correctly or the first large packet will be undeliverable and the connection will reset. If the target station is on the local network, Windows Sockets sets its packet size to the media packet size. Otherwise it defaults to 512 bytes. This size can be changed immediately after connect or accept via setsockopt.
NSPROTO_SPXII
SPXII features large Internet packet negotiation to maintain a best-fit size for packets and does not require programmer intervention. However, if the remote station does not support SPXII and negotiates down to standard SPX, the NSPROTO_SPX rules above are in effect.
Protocol | Media | Type | Data Pkt Size
NSPROTO_IPX | Ethernet | Ethernet II
802.3
802.2 | 1466
SNAP
Token Ring | 4 megabit
16 megabit

Protocol | Media | Type | Data Pkt Size
NSPROTO_SPX | Ethernet | Ethernet II
802.3
802.2 | 1454
SNAP
Token Ring | 4 megabit
16 megabit


IPX/SPX Data Structures

This information to be supplied at a later version.


IPX/SPX Controls

This section describes IPX/SPX socket options.

  • NSPROTO_IPX Socket Options


NSPROTO_IPX Socket Options

NSPROTO_IPX options are handled via getsockopt and setsockopt. Each option is accessed by setting level = NSPROTO_IPX and optname to a value given below.

level = NSPROTO_IPX

Option | Type | Default | Meaning
IPX_CHECKSUM | bool | off | When set, IPX checksums outgoing packets and verifies the checksum of incoming packets.
IPX_TXPKTSIZE | int | Media size to a max of 1466 | Sets maximum send datagram size. This size does not include the IPX header or any media headers that may also be used. May be increased to media size.
IPX_RXPKTSIZE | int | Media size to a max of 1466 | Sets maximum receive datagram size. This size does not include the IPX header or any media headers that may also be used. May be increased to media size.
IPX_TXMEDIASIZE | int | Primary board | Returns send media size which sets an upper bound for datagram size.
IPX_RXMEDIASIZE | int | Primary board | Returns receive media size which sets an upper bound for datagram size.
IPX_PRIMARY | bool | Primary | Restricts traffic to the primary network board.

level = NSPROTO_SPX

Option | Type | Default | Meaning
SPX_CHECKSUM | bool | off | When set, IPX checksums outgoing packets and verifies the checksum of incoming packets. Not supported on all platforms.
SPX_TXPKTSIZE | int | Media size to a max of 1466 | Sets maximum send datagram size. This size does not include the SPX header or any media headers that may also be used. May be increased to media size.
SPX_RXPKTSIZE | int | Media size to a max of 1466 | Sets maximum receive datagram size. This size does not include the SPX header or any media headers that may also be used. May be increased to media size.
SPX_TXMEDIASIZE | int | Primary board | Returns send media size minus SPX and media headers. This sets an upper bound for message segmentation packet size.
SPX_RXMEDIASIZE | int | Primary board | Returns receive media size minus SPX and media headers. This sets an upper bound for receive packet size.
SPX_RAWSPX | bool | off | When set, the IPX/SPX protocol header is passed with the data.

SPX_RAWSPX

When set, lets the application manage the IPX/SPX header. In this mode, Windows Sockets will not subsegment messages, restricting maximum send/recv message size to the underlying packet size. Packet size options are automatically adjusted to include the IPX/SPX headers. Fields settable by the application are detailed in wsipx.h.


IPX/SPX Function Specifics

This sections presents important specifics for IPX/SPX functions and header files.

  • IPX/SPX Header File


IPX/SPX Header File

The following lists the header file (WSIPX.H).

/*       WSIPX.H -- Winsock 2 Extensions for IPX networks
 *
 *  This file contains IPX/SPX specific information for use by
 *  Winsock 2 compabable applications.  Include this file below
 *  WINSOCK.H to enable IPX features in your application.
 *
 *                   Rev 0.3, Feb 23, 1995
 */

#ifndef  _WSIPX_
#define  _WSIPX_

#pragma pack(1)

/* Transparant sockaddr definition for address family AF_IPX */

typedef struct sockaddr_ipx {
   u_short  sa_family;
   u_char   sa_netnum[4];
   u_char   sa_nodenum[6];
   unsigned short sa_socket;

} SOCKADDR_IPX, *PSOCKADDR_IPX, FAR *LPSOCKADDR_IPX;

/* Protocol types within protocol family PF_IPX
 *
 * Protocol family PF_IPX reserves protocol id 0 - 255 for IP-conforming
 * protocol identifiers.
 *
 */

#define NSPROTO_UNSPEC        0
#define NSPROTO_IPX        1000
#define NSPROTO_SPX        1256
#define NSPROTO_SPXII      1257

/* Socket options for IPX level NSPROTO_IPX */

#define IPX_CATEGORY         NSPROTO_IPX

#define IPX_CHECKSUM         0x0001
#define IPX_PRIMARY          0x0002
#define IPX_TXPKTSIZE        0x1001
#define IPX_RXPKTSIZE        0x1002
#define IPX_TXMEDIASIZE      0x1003
#define IPX_RXMEDIASIZE      0x1004

/* Socket options for SPX level NSPROTO_SPX */

#define SPX_CATEGORY         NSPROTO_SPX

#define SPX_CHECKSUM         IPX_CHECKSUM
#define SPX_RAWSPX           0x0010
#define SPX_TXPKTSIZE        IPX_TXPKTSIZE
#define SPX_RXPKTSIZE        IPX_RXPKTSIZE
#define SPX_TXMEDIASIZE      IPX_TXMEDIASIZE
#define SPX_RXMEDIASIZE      IPX_RXMEDIASIZE

/*  net,node,socket portion of IPX header */

#define IPX_NET_SIZE    4
#define IPX_NODE_SIZE   6
#define IPX_SOCKET_SIZE 2

/* WSIpxAddr -- Ipx/Spx header net,node address structure */

typedef struct WSIpxAddrStruc
{
      u_long    Net;
      u_char    Node[IPX_NODE_SIZE];
      u_short   Socket;

} WSIpxAddr,*PWSIpxAddr,FAR *LPWSIpxAddr;

#define WSIpxNode0To3(pIpxAddr)         (*(UINT32*)(&((PWSIpxAddr*)pIpxAddr)->Node[0])
#define WSIpxNode4To5(pIpxAddr)         (*(UINT16*)(&((PWSIpxAddr*)pIpxAddr)->Node[3])

/* WSIpxHeader -- IPX header structure when in SOCK_RAW mode */

typedef struct WSIpxHeaderStruc
{
      u_short     Checksum;               // 0x00
      u_short     Length;                 // 0x02
      u_char      XportCtl;               // 0x04
      u_char      PktType;                // 0x05
      WSIpxAddr   DestAddr;               // 0x06
      WSIpxAddr   SrcAddr;                // 0x12
} WSIpxHeader, *PWSIpxHeader,FAR *LPWSIpxHeader;   // 0x1E total length

/* Standard IPX packet types */

#define   IPXTYPE_UNKNOWN         0x00
#define   IPXTYPE_RIP             0x01
#define   IPXTYPE_ECHO            0x02
#define   IPXTYPE_ERROR           0x03
#define   IPXTYPE_IPX             0x04
#define   IPXTYPE_SPX             0x05
#define   IPXTYPE_NCP             0x11
#define   IPXTYPE_NETBIOS         0x14
#define   IPXTYPE_INTERNET_BROADCAST   IPT_NETBIOS

/* WSSpxHeader -- SPX Header structure when in SPXL_SPXRAW mode. */

typedef struct WSSpxHeaderStruc
{
      WSIpxHeader  IpxHdr;              // 0x00
      u_char       ConnCtrl;            // 0x1E
      u_char       DataStreamType;      // 0x1F
      u_short      SrcConnId;           // 0x20
      u_short      DstConnId;           // 0x22
      u_short      SendSeq;             // 0x24
      u_short      AckSeq;              // 0x26
      u_short      AllocNum;            // 0x28
} WSSpxHeader, *PWSSpxHeader,FAR *LPWSSpxHeader;   // 0x2A (42) size

/* Connection Control Bits */

#define   SPX_SYSTEM_PACKET_BIT       0x80
#define   SPX_SEND_ACK_BIT            0x40
#define   SPX_ATTENTION_BIT           0x20
#define   SPX_END_OF_MESSAGE_BIT      0x10

/* Data Stream Types.
 *
 * Values in the range 0 - 0xfd are user-definable.
 */

#define   SPX_HANG_UP                 0xFE
#define   SPX_HANG_UP_ACK             0xFF

/* a sampling of well-known socket types in network hi-lo order.
 * use ntohl() for local representation.
 */

#define   IPXSKT_DYNAMIC                   0x0000
#define   IPXSKT_NCP                       0x5104
#define   IPXSKT_SAP                       0x5204
#define   IPXSKT_RIP                       0x5304
#define   IPXSKT_NETBIOS                   0x5504
#define   IPXSKT_DIAGNOSTICS               0x5604
#define   IPXSKT_PING                      0x8690

#endif /* _WSIPX_ */


DECnet

This section covers extensions to Windows Sockets 2 that are specific to DECnet. It also describes aspects of base Windows Sockets 2 functions that require special consideration or which may exhibit unique behavior.

Fast Facts

Protocol Name(s) | DNPROTO_NSP
Socket Type | SOCK_SEQPACKET
Description | Provides transport service over the DECnet network layer.
Address Family | AF_DECnet
Header File | WS2DNET.H


DECnet Overview

The Digital Network Architecture (DNA) consists of an architectural overview and a set of specifications defining various network protocol layers. DECnet refers to a set of products that implement the Digital Network Architecture. DECnet Phase IV, as introduced in 1982, supports peer-to-peer connectivity in both local and wide area networks.


The DNPROTO_NSP Protocol Family

DECnet Phase IV uses Network Services Protocol (NSP) as its transport layer.


AF_DECnet Address Families

The AF_DECnet Address families include:

DECnet Phase IV node addresses

DECnet Phase IV node addresses are hierarchical, indicating the a routing area and the node

number within that area. The binary format of the address is a 16-bit unsigned integer. The high-order 6 bits indicate the area, the low-order 10 bits are the node number within the area.

The ASCII format of the address is area.number with area in the range 1-63, and number in the range 1-1023.

For example: A DECnet node address in area 5, number 7 is represented as follows:

ASCII format | "5.7"
Binary value | 000101 0000000111.
Hexadecimal value | 0x1407

DECnet extended addressing

DECnet extended addressing allows the DECnet NSP transport to be run over the OSI routing layer. Sockets opened via AF_DECnet will assume that addresses of length 3-20 bytes are OSI-style addresses.

DECnet objects

DECnet client tasks specify the server task they want to communicate with by using network object number and task names. The DECnet object number is an 8-bit unsigned value. Object numbers in the range 1-127 are reserved as generic objects for Digital use. Numbers 1-128 are available for user-written generic objects.

If the object number is 0, then the network connect is done to a specific server task name. Task names are 1-16 byte ASCII strings.

For example:

#17 | FAL | Generic DECnet file access listener
#19 | NML | Generic DECnet network management listener
#0 | DEBUG_TASK | User-specified debug server task


The SOCK_SEQPACKET Socket Type

DECnet sockets use sequenced packets which maintain message boundaries across the network.


DECnet Data Structures

The DECnet structures and constants include WINSOCK2.H and WS2DNET.H. This section presents information about their constants and controls.

  • Manifest Constants (WINSOCK2.H)
  • Manifest Constants (WS2DNET.H)
  • Data Structures (WS2DNET.H)


Manifest Constants (WINSOCK2.H)

#define AF_DECnet           12    // DECnet address family
#define SOCK_SEQPACKET      5     // Socket type - Message-oriented


Manifest Constants (WS2DNET.H)

#define DNPROTO_NSP         1    // DECnet NSP transport protocol
#define SO_LINKINFO         7    // Get DECnet logical link information

#define DN_MAXADDL         20    // Maximum DECnet address length
#define DN_ADDL             2    // DECnet NSP address length
#define DN_MAXOPTL        16     // Maximum DECnet optional data
#define DN_MAXOBJL        16     // Maximum DECnet object name
#define DN_MAXACCL        40     // Maximum DECnet access string
                    // length (39 bytes + trailing zero)
    #define DN_MAXALIASL     128  // Maximum DECnet alias string length
    #define DN_MAXNODEL      256  // Maximum node string length

    // DECnet logical link states
    #define LL_INACTIVE         0    // logical link inactive
    #define LL_CONNECTING     1      // logical link connecting
    #define LL_RUNNING         2     // logical link running
    #define LL_DISCONNECTING     3   // logical link disconnecting

    // DECnet incoming access types
    #define DN_NONE          0x00
    #define DN_RO            0x01
    #define DN_WO            0x02
    #define DN_RW            0x03


Data Structures (WS2DNET.H)

This section lists address type information for the header files.

DECnet node address

// if a_len = 2, DECnet NSP transport & DECnet routing
// if a_len > 2, DECnet NSP transport & OSI routing
struct dn_naddr {
  unsigned short  a_len;    // address length - set to DN_ADDL
  unsigned char   a_addr[DN_MAXADDL]; // DECnet address
};

DECnet socket

// DECnet uses object names & numbers instead of ports
struct sockaddr_dn {
  unsigned short   sdn_family;    // AF_DECnet
  unsigned char    sdn_flags;         // Reserved - set to zero
  unsigned char    sdn_objnum;    // DECnet object number
  unsigned short   sdn_objnamel;  // DECnet object name length
  unsigned char    sdn_objname[DN_MAXOBJL]; // DECnet object name
  struct dn_naddr  sdn_add;         // DECnet address
};

DECnet node entity

struct nodeent_f {
  char FAR *n_name;              // pointer to name of DECnet node
  unsigned short n_addrtype;     // address type
  unsigned short n_length;       // address length
  unsigned char FAR *n_addr;     // pointer to DECnet address
  unsigned char FAR *n_params;
  unsigned char  n_reserved[16]; // Reserved
};

DECnet optional data

struct optdata_dn {
  unsigned short  opt_status;          // status return
  unsigned short  opt_optl;            // length of data
  unsigned char   opt_data[DN_MAXOPTL]; // Optional data
};

DECnet outgoing access control data

struct accessdata_dn {
  unsigned short  acc_accl;             // account length
  unsigned char   acc_acc[DN_MAXACCL];  // account string
  unsigned short  acc_passl;            // password length
  unsigned char   acc_pass[DN_MAXACCL]; // password string
  unsigned short  acc_userl;            // user length
  unsigned char   acc_user[DN_MAXACCL]; // user string
};

DECnet incoming access control

//  DECnet incoming access control information
struct dnet_accent
{
  unsigned char dac_status;
  unsigned char dac_type;  // DN_NONE, etc.
  char dac_username[DN_MAXACCL];
  char dac_password[DN_MAXACCL];
};

DECnet call data

struct  calldata_dn {
struct optdata_dn {
  unsigned short  opt_status;
  unsigned short  opt_optl;
  unsigned char   opt_data[DN_MAXOPTL];
};
struct accessdata_dn {
  unsigned short  acc_accl;
  unsigned char   acc_acc[DN_MAXACCL];
  unsigned short  acc_passl;
  unsigned char   acc_pass[DN_MAXACCL];
  unsigned short  acc_userl;
  unsigned char   acc_user[DN_MAXACCL];
}
};

DECnet logical link

struct linkinfo_dn {
  unsigned short  idn_segsize;
  unsigned char   idn_linkstate;
};


DECnet Function Details

This section presents connection information for DECnet functions.

  • Connections Using Accept/WSAAccept/ WSPAccept
  • Structure Information for Bind/WSPBind
  • Connections using Connect/WSAConnect/WSPConnect
  • Addressing with Getpeername/WSPGetPeerName
  • Receiving Local Name with Getsockname/WSPGetSockName
  • Using Getsockopt/WSPGetSockOpt
  • Using Socket/WSASocket/WSPSocket
  • DECnet Out-of-band data


Connections Using Accept/WSAAccept/ WSPAccept

This section describes various data connections for accept functions.

Immediate Accept with no optional or access data

In order to accept a connection on a DECnet socket, the parameter addr should point to a sockaddr_dn structure.

#include <ws2dnet.h>

SOCKET WSAAPI accept ( SOCKET s, struct sockaddr_dn FAR * addr, int FAR * addrlen );

SOCKET WSAAPI WSAAccept ( SOCKET s, struct sockaddr_dn FAR * addr, int FAR * addrlen, LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData );

SOCKET WSPAPI WSPAccept( SOCKET s, struct sockaddr_dn FAR * addr, int FAR * addrlen, LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData,
int FAR * lpErrno );
addr A pointer to a sockaddr_dn structure which receives the address of the connecting entity, as known to the communications layer.

Deferred accept with optional and access data

DECnet sockets support both immediate and deferred accepts. It also supports the exchange of up to 16 bytes of optional data on accept and connect. It also supports the receipt of DECnet access control information by the server from the client on a connect request.

#include <ws2dnet.h>

SOCKET WSAAPI WSAAccept ( SOCKET s, struct sockaddr_dn FAR * addr, int FAR * addrlen, LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData );

SOCKET WSPAPI WSPAccept( SOCKET s, struct sockaddr_dn FAR * addr, int FAR * addrlen, LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData,
int FAR * lpErrno );

DECnet optional data is passed in an optdata_dn structure. Access control data is passed in an accessdata_dn structure.

In the CALLBACK function, the lpCallerData should point to a calldata_dn structure which contains concatenated opdata_dn and accessdata_dn structures. If lpCallerData is set to NULL, no additional data will be read from the caller. If either the opdata_dn.opt_optl or the accessdata_dn.acc_userl are set to zero, that portion of the structure will be ignored.

The accept only reads accessdata_dn, it does not write it, so only optdata_dn will be returned by the server. The lpCalleeData pointer should point to a buffer containing the opdata_dn structure. If lpCalleeData is set to NULL no optional data will be read from the server.


Structure Information for Bind/WSPBind

In order to bind a local DECnet address to a socket, the parameter name should point to a sockaddr_dn structure.

#include <ws2dnet.h>

int WSAAPI bind (SOCKET s, const struct sockaddr_dn FAR * name, int namelen);

int WSAAPI WSPBind ( SOCKET s, const struct sockaddr_dn FAR * name, int namelen, int FAR * lpErrno );
name A pointer to a sockaddr_dn structure which contains the DECnet address to be bound to this socket.


Connections using Connect/WSAConnect/WSPConnect

This section provides connection information using Connect functions.

Connect with no optional or access data

In order to establish a connection to a DECnet peer, the parameter name should point to a sockaddr_dn structure.

#include <ws2dnet.h>

int WSAAPI connect ( SOCKET s, const struct sockaddr_dn FAR * name,
int namelen );

int WSAAPI WSAConnect ( SOCKET s, const struct sockaddr_dn FAR * name,
int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData,
GROUP g, LPQOS lpSQOS, LPQOS lpGQOS );

int WSPAPI WSPConnect( SOCKET s, const struct sockaddr_dn FAR * name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, int FAR * lpErrno );
name A pointer to a sockaddr_dn structure which contains the DECnet address and object to which the socket is to be connected.

Optional and access data on connect

DECnet sockets support supports the exchange of up to 16 bytes of optional data on a WSAConnect. It also supports the sending of DECnet access control information from the client to the server on a connect request.

#include <ws2dnet.h>

int WSAAPI WSAConnect ( SOCKET s, const struct sockaddr_dn FAR * name,
int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData,
GROUP g, LPQOS lpSQOS, LPQOS lpGQOS );

int WSPAPI WSPConnect( SOCKET s, const struct sockaddr_dn FAR * name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS,LPQOS lpGQOS, int FAR * lpErrno );

lpCallerData | A pointer to the user data that is to be transferred from the client to the server during connection establishment.
lpCalleeData | A pointer to the optional data that is to be transferred back from the server during connection establishment.

DECnet optional data is passed in an optdata_dn structure. Access control data is passed in an accessdata_dn structure.

The lpCallerData should point to a calldata_dn structure which contains concatenated opdata_dn and accessdata_dn structures. If lpCallerData is set to NULL, no additional data will be sent to the server. If either the opdata_dn.opt_optl or the accessdata_dn.acc_userl are set to zero, that portion of the structure should be ignored.

If lpCalleeData is set to NULL, no optional data will be read from the server. If either the opdata_dn.opt_optl or the accessdata_dn.acc_userl are set to zero, that structure should be ignored. The accept only returns optional data, not access data so the lpCalleeData pointer should point to a buffer containing the opdata_dn structure. If lpCalleeData is set to NULL no optional data will be read from the server.


Addressing with Getpeername/WSPGetPeerName

To get the address of the DECnet peer to which a socket is connected, the parameter name should point to a sockaddr_dn structure.

#include <ws2dnet.h>

int WSAAPI getpeername ( SOCKET s, struct sockaddr_dn FAR * name, int FAR * namelen );

int WSPAPI WSPGetPeerName( SOCKET s, struct sockaddr_dn FAR * name, int FAR * namelen, int FAR * lpErrno );
name A pointer to a sockaddr_dn structure that will return the DECnet address of the DECnet peer to which a socket is connected.


Recieving Local Name with Getsockname/WSPGetSockName

To get the local name for a DECnet socket, the parameter name should point to a sockaddr_dn structure.

#include <ws2dnet.h>

int WSAAPI getsockname ( SOCKET s, struct sockaddr_dn FAR * name, int FAR * namelen );

int WSPAPI WSPGetSockName( SOCKET s, struct sockaddr_dn FAR * name, int FAR * namelen, int FAR * lpErrno );
name A pointer to a sockaddr_dn structure that will return the local name to which a DECnet socket is connected.


Using Getsockopt/WSPGetSockOpt

Description

The SO_LINKINFO socket option returns a struct linkinfo_dn containing the current state of the specified DECnet logical link.

int WSPAPI WSPGetSockOpt(SOCKET s, int level, int optname, char FAR * optval, int far * optlen, int FAR * lpErrno);

s | descriptor identifying socket
level | DNPROTO_NSP
optname | SO_LINKINFO
optval | struct FAR * linkinfo_dn
optlen | sizeof(struct linkinfo_dn)
lpErrno | pointer to error code

Return Values

If no error occurs, WSPGetSockOpt returns 0 and the linkinfo_dn structure pointed to by optval will contain the current transport segment size and logical link state. See the LL_* manifest constants for valid link states. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code is available in lpErrno.


Using Socket/WSASocket/WSPSocket

To create a socket that is bound to a DECnet service provider, the following values should passed to the socket call.

#include <ws2dnet.h>

SOCKET WSAAPI socket ( int af, int type, int protocol );

SOCKET WSAAPI WSASocket(int af, int type, int protocol, ...)

SOCKET WSPAPI WSPSocket(int af, int type, int protocol, ...)

af = AF_DECnet | DECnet address family
type = SOCK_SEQPACKET | Sequenced packets (message-oriented)
protocol = DNPROTO_NSP | DECnet NSP transport protocol


DECnet Out-of-band data

DECnet supports the sending and receiving of out-of-band data via the MSG_OOB flag for recv and send. If a send with the MSG_OOB flag is sent, the recv must be posted with MSG_OOB in order to read the data. To check for the presence of out-of-band data, use select with exceptfds set, or a WSAAsyncSelect with FD_OOB set.

DECnet does not support inline out-of-band data via the setsockopt SO_OOBINLINE flag.


DECnet-specific Extended Functions Identifiers

This section presents the DECnet-specific extensions to the Windows Sockets 2 specification.

The Windows Sockets 2 function extension mechanism works as follows: a call is made to WSAIoctl with the control code SIO_GET_EXTENSION_FUNCTION_POINTER which returns a function pointer to a specified extension function.

The following DECnet-specific extension identifiers have been allocated by the WS2 identifier clearinghouse.

Note We reserve 32 in each block.

//
//  DECnet
//
#define WS2API_DECNET_dnet_addr                 1
#define WS2API_DECNET_dnet_eof                  2
#define WS2API_DECNET_dnet_getacc               3
#define WS2API_DECNET_dnet_getalias             4
#define WS2API_DECNET_dnet_htoa                 5
#define WS2API_DECNET_dnet_ntoa                 6
#define WS2API_DECNET_getnodeadd                7
#define WS2API_DECNET_getnodebyaddr             8
#define WS2API_DECNET_getnodebyname             9
#define WS2API_DECNET_getnodename              10
//
// Next ones start at 33
//


dnet_addr

The dnet_addr identifier converts an ASCIZ DECnet Phase IV node address string to a binary address.

#include <ws2dnet.h>

struct dn_naddr FAR * WSAAPI dnet_addr(const char FAR *cp);
cp Specifies the address of a character string that contains a DECnet node address in the form a.n (area.node). For example, 9.440 is a DECnet Phase IV node number.

Return Values

dnet_addr returns a pointer to dn_naddr structure

If successful, it returns a pointer to a dn_naddr structure which contains a binary DECnet address. Applications should copy this data before issuing another dnet_addr call. Otherwise, it returns a NULL pointer.


dnet_eof

Description

Test a DECnet socket for an end-of-file condition.

int WSAAPI dnet_eof(SOCKET s);
s Specifies DECnet socket to test.

Return Values

If the connection is still active (either in a running or connected state), it returns 0. If the connection is inactive, a 1 is returned.


dnet_getacc

Retrieve local access control for incoming DECnet connection based on the specified user name.

#include <ws2dnet.h>

struct dnet_accent FAR * WSAAPI dnet_getacc(struct dnet_accent FAR *nacc )
nacc Pointer to the incoming access control record. nacc.dac_username contains the user name. This ASCIZ character string has a maximum length of DN_MAXACCL.

Return Values

If successful, it returns a pointer to a dnet_accent structure. Applications should copy this data before issuing another dnet_getacc call. Otherwise, it returns a NULL pointer.


dnet_getalias

The dnet_getalias function returns any default access control information associated with a specific node.

char FAR * WSAAPI dnet_getalias(const char FAR *node)

The following ASCIZ strings are all valid returns:

"node"

"node/username"

"node/username/password"

"node/username/password/account"

"node/username//account"

node Pointer to the node name for which dnet_getalias should search.

Return Values

The call returns the address of a static buffer that contains the information from the local DECnet node database. Applications should copy this data before issuing another dnet_getalias call.


dnet_htoa

The dnet_htoa function searches the local node database. If it finds the node name for the specified node address, it returns a pointer to an ASCIZ DECnet name string. Otherwise, it returns an ASCIZ node address string.

#include <ws2dnet.h>

char FAR *WSAAPI dnet_htoa(const struct dn_naddr FAR *add);
add Specifies the address of a dn_naddr structure that contains the node number for which to search.

Return Values

The function returns the address of a static buffer that contains the node string. This string must be copied before dnet_htoa is called again.


dnet_ntoa

The dnet_ntoa function converts a DECnet node address from binary to ASCIZ format. It converts the pointer to a dn_naddr to a string in the form 9.123, for example.

#include <ws2dnet.h>

char FAR *WSAAPI dnet_ntoa(const struct dn_naddr FAR *add);
add Specifies the address of a dn_naddr structure that contains the node number to convert.

Return Values

The function returns a pointer to a static string that contains the node address. This string must be copied before dnet_ntoa is called again.


getnodeadd

The getnodeadd function returns the local node's DECnet address.

#include <ws2dnet.h>

struct dn_naddr FAR *WSAAPI getnodeadd(void);

Return Values

The function returns the address of a static dn_naddr structure containing the local node's DECnet address. Applications should copy this data before issuing another getnodeadd call. If DECnet is not installed, it returns a NULL pointer


getnodebyaddr

The getnodebyaddr function searches for a DECnet node name that matches a specified DECnet address. The address is a 16-bit binary DECnet address, where the high 6 bits are the DECnet area number and the low 10 bits are the DECnet node number. DECnet Phase IV node names consist of 1 to 6 alphanumeric characters with at least one alphabetic character.

#include <ws2dnet.h>

struct nodeent_f  FAR *WSAAPI getnodebyaddr(const unsigned char FAR *addr, int len, int type);

addr | Pointer to the address for which getnodebyaddr should search.
len | Length in bytes of the requested address (range DN_ADDL to DN_MAXADDL).
type | Address family of the address (AF_DECnet).

Return Values

The function returns a pointer to a static nodeent_f structure. The application must copy this data before issuing another getnodebyaddr call. If the end of file is reached, a NULL pointer is returned.


getnodebyname

The getnodebyname function searches for a DECnet node address that matches the specified DECnet node name. DECnet Phase IV node names consist of 1 to 6 alphanumeric characters with at least one alphabetic character.

#include <ws2dnet.h>

struct nodeent_f  FAR *WSAAPI getnodebyname(const char FAR *);
name Pointer to an ASCIZ node name for which to search.

Return Values

The function returns a pointer to a static nodeent_f structure. The application must copy this data before issuing another getnodebyaddr call. If the end of file is reached, a NULL pointer is returned.


getnodename

The getnodename function returns the name of the local DECnet node. DECnet Phase IV node names consist of 1 to 6 alphanumeric characters with at least one alphabetic character.

char FAR *WSAAPI getnodename(void);

Return Values

The function returns the address of a static string that contains the local node's ASCIZ DECnet name, or a NULL pointer if DECnet is not installed. The maximum size for a returned string is DN_MAXNODEL. The application must copy this data before issuing another getnodename call.


DECnet Header File

Partial contents of DECnet header file WS2DNET.H are defined as follows:

//************************************************************************
//  Winsock V2.0  DECnet definitions        File: WS2DNET.H
///***********************************************************************
//  Copyright (c) 1995, All Rights Reserved
//  Digital Equipment Corporation, Littleton, MA.
//************************************************************************

#ifndef WS2DNET_H
#define WS2DNET_H

#include <winsock2.h>

//
//  DECnet Winsock Definitions
//
#define DNPROTO_NSP      1  // DECnet NSP transport protocol number

#define DN_MAXADDL      20  // maximum DECnet address length
#define DN_ADDL          2  // DECnet NSP address length
#define DN_MAXOPTL      16  // Maximum DECnet optional data length
#define DN_MAXOBJL      16  // Maximum DECnet object name length
#define DN_MAXACCL      39  // Maximum DECnet access string length
#define DN_MAXALIASL   128  // Maximum DECnet alias string length
#define DN_MAXNODEL      7  // Maximum DECnet Phase IV node string length

//
//  DECnet address structure
//
typedef struct dn_naddr {
    unsigned short    a_len;                // length of address
    unsigned char   a_addr[DN_MAXADDL];     // address as bytes
} DNNADDR, FAR *LPDNNADDR;

//
//  DECnet socket address structure
//
typedef struct sockaddr_dn {
    unsigned short    sdn_family;       // AF_DECnet
    unsigned char    sdn_flags;         // flags
    unsigned char    sdn_objnum;        // object number
    unsigned short    sdn_objnamel;     // size of object name
    char sdn_objname[DN_MAXOBJL];       // object name
    struct dn_naddr  sdn_add;           // node address
} SOCKADDRDN, FAR *LPSOCKADDRDN;

#define sdn_nodeaddrl    sdn_add.a_len    // node address length
#define sdn_nodeaddr    sdn_add.a_addr    // node address

//  Common DECnet object numbers (used in sockaddr_dn)
#define DNOBJECT_FAL    17         // file access listener
#define DNOBJECT_NICE    19        // network management
#define DNOBJECT_DTERM    23       // remote terminals
#define DNOBJECT_MIRROR    25      // loopback mirror
#define DNOBJECT_EVR    26         // event receiver
#define DNOBJECT_MAIL11    27      // Mail-11 service
#define DNOBJECT_PHONE    29       // phone utility
#define DNOBJECT_CTERM    42       // command terminals
#define DNOBJECT_DTR    63         // data test receiver

//
//  DECnet node structure
//
typedef struct    nodeent_f {
    char         FAR * n_name;        // name of node
    unsigned short    n_addrtype;     // node address type
    unsigned short    n_length;       // address length
    unsigned char    FAR * n_addr;    // address
    unsigned char    FAR * n_params;  // node parameters
    unsigned char   n_reserved[16];   // Reserved
} NODEENTF, FAR *LPNODEENTF;

//
//  DECnet set/get DSO_CONDATA, DSO_DISDATA (optional data) structure
//
typedef struct optdata_dn {
    unsigned short    opt_status;            // extended status return
    unsigned short    opt_optl;              // user data length
    unsigned char   opt_data[DN_MAXOPTL];    // user data
} OPTDATADN, FAR *LPOPTDATADN;

//
//  DECnet set/get DSO_CONACCESS access (control data) structure
//
typedef struct accessdata_dn {
    unsigned short    acc_accl;                 // account string length
    unsigned char    acc_acc[DN_MAXACCL+1];     // account string
    unsigned short    acc_passl;                // password string length
    unsigned char    acc_pass[DN_MAXACCL+1];    // password string
    unsigned short    acc_userl;                // user string length
    unsigned char    acc_user[DN_MAXACCL+1];    // user string
} ACCESSDATADN, FAR *LPACCESSDATADN;

//
//  DECnet call data structure (concatenated access and optional data)
//
typedef struct calldata_dn {
    struct optdata_dn       optdata_dn;
    struct accessdata_dn    accessdata_dn;
} CALLDATADN, FAR *LPCALLDATADN;

//
//  DECnet incoming access control structure
//
typedef struct dnet_accent {
    unsigned char dac_status;      // Reserved
    unsigned char dac_type;        // DN_NONE, etc.
    char dac_username[DN_MAXACCL+1];
    char dac_password[DN_MAXACCL+1];
} DNETACCENT, FAR *LPDNETACCENT;

#define DN_NONE          0x00
#define DN_RO            0x01
#define DN_WO            0x02
#define DN_RW            0x03

//*********************************************************************
//  DECnet function prototypes
//*********************************************************************
struct dn_naddr FAR *WSAAPI dnet_addr(const char FAR *);
int WSAAPI dnet_eof(SOCKET);
struct dnet_accent FAR *WSAAPI dnet_getacc(const struct dnet_accent FAR *);
char FAR *WSAAPI dnet_getalias(const char FAR *);
char FAR *WSAAPI dnet_htoa(const struct dn_naddr FAR *);
char FAR *WSAAPI dnet_ntoa(const struct dn_naddr FAR *);
struct dn_naddr FAR *WSAAPI getnodeadd(void);
struct nodeent_f FAR *WSAAPI getnodebyaddr(const unsigned char FAR *addr, int, int);
struct nodeent_f FAR *WSAAPI getnodebyname(const char FAR *);
char FAR *WSAAPI getnodename(void);

#endif    // WS2DNET_H


OSI

The section presents OSI transport information.

  • OSI Introduction
  • OSI Overview
  • OSI Data Structures
  • OSI Controls
  • OSI Function Specifics
  • OSI Header File


OSI Introduction

This section covers extensions to Windows Sockets 2 that are specific to OSI transports. It also describes aspects of base Windows Sockets 2 functions that require special consideration or which may exhibit unique behavior when used with OSI transports.

Fast Facts

Protocol Name(s) | TP4/CLNS, TP4/NULL, etc.
Description | Provides OSI transport services over OSI networking layer: CLTS for unreliable datagrams and COTS for reliable connection-orientated message streams.
Address Family | AF_OSI
Header File | WS2OSI.H


OSI Overview

The International Organization for Standardization (ISO) produce a set of international standards to facilitate interconnection of computer systems. The Open Systems Interconnection (OSI) Reference Model subdivides the set into a series of layers. Windows Sockets allows an application to use OSI Transport protocols.

Examples of OSI profiles that may be implemented are:

  • TP4/CLNS - Transport class 4 over Connectionless-mode Network Service
  • TP4/NULL - Transport class 4 over Null Network Service
  • TP0/CONS - Transport class 0 over Connection-mode Network Service
  • NULL/CONS - Null Transport over Connection-mode Network Service
  • TP0/TCP - Transport class 0 over TCP/IP (RFC1006)

The OSI profile is designated either by the protocol parameter or the lpProtocolInfo parameter to the WSASocket API. The TP4/NULL profile is a subset of the TP4/CLNS profile, and is selected by the addressing information. The default OSI profile is TP4/CLNS.

An application must use the WSAPROTOCOL_INFO structure returned by WSAEnumProtocols to discover the services provided by a particular OSI profile. For example not all OSI profiles support Connect and disconnect data.


Expedited Data

OSI protocols may support expedited data. Expedited data is not subject to the flow control procedures for normal data, and may overtake normal data.


Qualified Data

The ISO 8208/X.25 protocol supports qualified data. Qualified data is sent by using the WSAIoctl function to mark the following data as qualified, and then using the normal Windows Sockets send functions. Qualified data is received by using the WSAIoctl function to wait for notification of qualified data, and then using the normal Windows Sockets recv functions.


Reset

The ISO 8208/X.25 protocol supports resets. A reset may be generated by using the WSAIoctl function. A reset is notified to the application using the WSAIoctl function. Two bytes of reset data are permitted. These are interpreted as reset cause and reset diagnostic. For further details of this data see the X.25 specification.


OSI Quality Of Service

The provider specific parameters in the Flow Spec are encoded in a Type/Length/Data format to enable multiple parameters to be provided.

For example ISO 8208/X.25 call facilities may be specified by using the type OSI_PARAM_ID_X25_CALL_FACILITY.


Option Profiles

OSI protocols typically have a large number of options. These options may include preferred class, alternative classes, timers, checksums, lifetime, and others. An option profile name may be used to select a set of options available in a particular vendors OSI protocol implementation. The Windows Sockets specification does not define the options that may be selected.

Option profile names are specified in the OSI address structure. If an option profile name is not specified, the OSI protocol will use its default option profile.


Address Format

Two address formats for the OSI protocol are defined in this section. The SOCKADDR_TP format is retained for compatibility with Windows Sockets 1.1 OSI protocols. Windows Sockets 2 OSI protocols support the SOCKADDR_OSITP format. It contains a Transport Selector (TSEL), Network Service Access Point (NSAP), Sub Network address (SNPA), extended addressing information, and the option profile name.

The SNPA follows the rules of the Sub Network in use. For example an SNPA would contain a 6 byte MAC address followed by a 1 byte Link Service Access Point (LSAP) giving a 7 byte SNPA.

Some X.25 protocols use connect user data to select the listening socket. The extended addressing information contains connect user data. This field must not be specified for other OSI protocols.

The address structure also contains the option profile name. If the name length is zero, the default option profile is used.

The TP4/NULL OSI protocol profile is selected by using the TP4/CLNS protocol, selecting a zero length NSAP, and specifying the MAC address and LSAP in the Sub Network address field.


OSI Data Structures

The following structure is used to encode the provider specific parameters in the flow specification:

typedef struct _osispecflowparam
{
    u_short paramID;        // Parameter ID.
    u_short paramLength;    // Length of following data.
    u_char  param;          // Parameter data.
} OSISPECFLOWPARAM;


OSI Controls

This section describes OSI control features using Ioctls and socket options.

  • Ioctls
  • Socket Options


Ioctls

The following commands are available:

Command | Semantics
SIO_OSI_X25_GET_RESET_DATA | This command will wait for an ISO 8208/X.25 reset to occur, and will return the reset data associated with the reset. No input buffer is required. The two bytes of reset data will be copied to the output buffer. The WSAENOPROTOOPT error code is indicated for service providers that do not support X.25 resets.
SIO_OSI_X25_GENERATE_RESET | Generate an ISO 8208/X.25 reset. No output buffer is required, the two byes of reset data will be obtained from the input buffer. The WSAENOPROTOOPT error code is indicated for service providers that do not support X.25 resets.
SIO_OSI_X25_SEND_QUALIFIED | This command is used to indicate that the next message sent using one of the send functions, or WSASend, will be sent as Qualified data. No buffers are required. It is not necessary to call this function for subsequent sends of the same message where the MSG_PARTIAL flag has been used. The WSAENOPROTOOPT error code is indicated for service providers that do not support X.25 Qualified data.
SIO_OSI_X25_GET_QUALIFIED | This command will wait until the next message that will be received by the recv or WSARecv functions will be ISO 8208/X.25 Qualified data. This command will only complete once for each message received, even if the MSG_PARTIAL flag is returned. The WSAENOPROTOOPT error code is indicated for service providers that do not support X.25 Qualified data.


Socket Options

The following socket options are supported for setsockopt and getsockopt. The Type identifies the type of data addressed by optval.

level = SOL_SOCKET

Value | Type | Meaning
SO_EXPEDITED | BOOL | Negotiate expedited data.
SO_X25_CONFIRM_DELIVERY | BOOL | ISO 8208/X.25 Delivery Confirmation

SO_EXPEDITED
This option is negotiated during connection establishment. The setsockopt function must be used before the connection is established to specify the proposed option. The getsockopt function may be used after the circuit has been established to retrieve the final negotiated option. See ISO 8073 for further details.
SO_X25_CONFIRM_DELIVERY
This option controls the state of the Delivery Confirmation bit (D-bit) for X.25 protocols. If the D-bit is set, end-to-end confirmation of data occurs. The SO_X25_CONFIRM_DELIVERY option may be used to change the state of the D-bit many times during the life of a connection.


OSI Function Specifics

This section describes provider-specific parameters for Quality of Service and lists the OSI header file.

  • Quality Of Service
  • OSI Header File


Quality Of Service

The provider specific parameters in the Flow Spec are encoded in a Type/Length/Data format to enable multiple parameters to be provided. The OSISPECFLOWPARAM structure is used to encode the parameter.

The following parameter types are defined:

Parameters | Type | Meaning
OSI_PARAM_ID_X25_CALL_FACILITY | u_char[] | ISO 8208/X.25 call facilities.

OSI_PARAM_ID_X25_CALL_FACILITY
This parameter specifies the ISO 8208/X.25 call facilities to be used. The format of the data is the same as is coded in an X.25 call request/call confirm packet. For further details see the X.25 specification.


OSI Header File

/*       WS2OSI.H -- Winsock 2 Extensions for OSI protocols
 *
 *  This file contains OSI specific information for use by
 *  Winsock 2 compabable applications.  Include this file below
 *  WINSOCK.H to enable OSI features in your application.
 *
 *                   Rev 0.2, July 28, 1995
 */

#ifndef  _WS2OSI_
#define  _WS2OSI_

/*
 * Protocol values for ISO transport protocols.
 */

#define ISOPROTO_TP_CONS   25           // Transport over CONS
#define ISOPROTO_CLTP_CONS tba          // Connectionless Transport
                                        // over CONS

#define ISOPROTO_TP4_CLNS  29           // Transport class 4 over CLNS
#define ISOPROTO_CLTP_CLNS 30           // Connectionless Transport
                                        // over CLNS

#define ISOPROTO_X25       32           // X.25
#define ISOPROTO_X25PVC    tba          // Permanent Virtual Circuit
#define ISOPROTO_X25SVC    ISOPROTO_X25 // Switched Virtual Circuit

#define ISOPROTO_TP        ISOPROTO_TP4_CLNS
#define ISOPROTO_CLTP      ISOPROTO_CLTP_CLNS

#define ISOPROTO_TP0_TCP   tba          // Transport class 0 over TCP
                                        // (RFC1006)

/*
 *   The maximum size of the transport address (tp_addr field of a
 *   sockaddr_tp structure) is 64. The maximum size of the transport
 *   address (tp_addr field of a sockaddr_ositp structure) is 126.
 */

#define ISO_MAX_ADDR_LENGTH 64
#define ISO_MAX_EXT_ADDR_LENGTH 126

/*
 *   There are three types of ISO addresses, hierarchical,
 *   extended-hierarchical and non-hierarchical.  For hierarchical and
 *   extended-hierarchical, the tp_addr field contains both the
 *   transport selector and the NSAP. Extended-hierarchical addresses
 *   also contain a Sub Network address, extended addressing for X.25,
 *   and an option profile name.
 *   For non-hierarchical addresses, tp_addr contains only the transport
 *   address, which must be translated by the ISO TP4 transport provider
 *   into the transport selector and network address.
 */

#define ISO_HIERARCHICAL            0
#define ISO_NON_HIERARCHICAL        1
#define ISO_EXTENDED_HIERARCHICAL   2

/*
 *   The format of the address structure (sockaddr) to pass to Windows
 *   Sockets APIs.
 *
 */

typedef struct sockaddr_tp {
   u_short tp_family;          // Always AF_ISO
   u_short tp_addr_type;       // ISO_HIERARCHICAL or
                               // ISO_NON_HIERARCHICAL
   u_short tp_taddr_len;       // Length of transport address, <= 52
   u_short tp_tsel_len;        // Length of transport selector, <= 32
                               // 0 if ISO_NON_HIERARCHICAL
   u_char tp_addr[ISO_MAX_ADDR_LENGTH];
} SOCKADDR_TP, *PSOCKADDR_TP, *LPSOCKADDR_TP;

#define ISO_SET_TP_ADDR(sa_tp, port, portlen, node, nodelen)       \
            (sa_tp)->tp_family = AF_ISO;                           \
            (sa_tp)->tp_addr_type = ISO_HIERARCHICAL;              \
            (sa_tp)->tp_tsel_len = (portlen);                      \
            (sa_tp)->tp_taddr_len = (portlen) + (nodelen);         \
            memcpy(&(sa_tp)->tp_addr, (port), (portlen));          \
            memcpy(&(sa_tp)->tp_addr[portlen], (node), (nodelen));

typedef struct sockaddr_ositp {
   u_short tp_family;          // Always AF_ISO
   u_short tp_addr_type;       // ISO_EXTENDED_HIERARCHICAL
   u_short tp_tsel_len;        // Length of transport selector, <= 32
   u_short tp_nsap_len;        // Length of transport address, <= 20
   u_short tp_snet_len;        // Sub Network address length, <= 18
   u_short tp_ext_addr_len;    // Extended address length, <= 40
   u_short tp_optname_len;     // Option profile name length, <= 16
   u_char  tp_addr[ISO_MAX_EXT_ADDR_LENGTH];
} SOCKADDR_OSITP, *PSOCKADDR_OSITP, *LPSOCKADDR_OSITP;

#define ISO_SET_OSITP_ADDR(sa_tp, tsel, tsellen, nsap, nsaplen,    \
                           snpa, snpalen, extaddr, extaddrlen,     \
                           optname, optnamelen) {                  \
            u_char * paddr;                                        \
            (sa_tp)->tp_family = AF_ISO;                           \
            (sa_tp)->tp_addr_type = ISO_EXTENDED_HIERARCHICAL;     \
            (sa_tp)->tp_tsel_len = (tsellen);                      \
            (sa_tp)->tp_nsap_len = (nsaplen);                      \
            (sa_tp)->tp_snet_len = (snpalen);                      \
            (sa_tp)->tp_ext_addr_len = (extaddrlen);               \
            (sa_tp)->tp_optname_len = (optnamelen);                \
            memcpy(&(sa_tp)->tp_addr, (tsel), (tsellen));          \
            paddr = &(sa_tp)->tp_addr[tsellen];                    \
            memcpy(paddr, (nsap), (nsaplen));                      \
            paddr += (nsaplen);                                    \
            memcpy(paddr, (snpa), (snpalen));                      \
            paddr += (snpalen);                                    \
            memcpy(paddr, (extaddr), (extaddrlen));                \
            paddr += (extaddrlen);                                 \
            memcpy(paddr, (optname), (optnamelen));                \
        }

#define ISO_OSITP_ADDR_LEN(sa_tp)                                  \
            (sa_tp)->tp_tsel_len +                                 \
            (sa_tp)->tp_nsap_len +                                 \
            (sa_tp)->tp_snet_len +                                 \
            (sa_tp)->tp_ext_addr_len +                             \
            (sa_tp)->tp_optname_len

#endif // _WS2OSI_


ATM-Specific Extensions

This section presents information describing the Asynchronous Transfer Mode (ATM) specific extensions.

  • ATM Introduction
  • ATM Overview
  • ATM Data Structures
  • ATM Controls
  • ATM Function Specifics
  • ATM-specific QOS Extension
  • ATM Header File


ATM Introduction

This section describes the Asynchronous Transfer Mode (ATM) specific extensions needed to support the native ATM services as exposed and specified in the ATM Forum User Network Interface (UNI) specification version 3.x (3.0 and 3.1). This document supports AAL type 5 (message mode) and user-defined AAL. Future versions of this document will support other types of AAL as well as UNI 4.0 after it's finalized.

Fast Facts

Protocol Name(s) | ATMPROTO_AAL5, ATMPROTO_AALUSER
Description | ATM AAL5 provides a transport service which is connection-oriented, message boundary preserved, and QOS guaranteed. ATMPROTO_AALUSER is a user-defined AAL.
Address Family | AF_ATM
Header File | WS2ATM.H


ATM Overview

ATM is an emerging high-speed networking technology which is applicable to both LAN and WAN arenas. An ATM network simultaneously transports a wide variety of network traffic -- voice, data, image, and video. It provides users with a guaranteed quality of service on a per Virtual Channel (VC) basis.


ATM Data Structures

A new address family, AF_ATM, is introduced for native ATM services, and the corresponding "sockaddr" structure, sockaddr_atm, is defined below. To open a socket for native ATM services, parameters in socket should contain "AF_ATM", "SOCK_RAW", and "ATMPROTO_AAL5" or "ATMPROTO_AALUSER", respectively.

struct sockaddr_atm {
    u_short satm_family;        /* address family should be AF_ATM  */
    ATM_ADDRESS satm_number;    /* ATM address                      */
    ATM_BLLI satm_blli;         /* B-LLI                            */
    ATM_BHLI satm_bhli;         /* B-HLI                            */
};

Members

satm_family
Identifies the address family, which is AF_ATM in this case.
satm_number
Identifies the ATM address which could be either in E.164 or NSAP-style ATM End Systems Address format. See next section for more details about the ATM_ADDRESS structure. This field will be mapped to the Called Party Number IE(Information Element) if it is specified in bind/WSPBind for a listening socket, or in connect/WSAConnect/WSPConnect/WSAJoinLeaf/WSPJoinLeaf for a connecting socket. It will be mapped to the Calling Party Number IE if specified in bind/WSPBind for a connecting socket.
satm_blli
Identifies the fields in the B-LLI Information Element which are used along with satm_bhli to identify an application. See the section below for more details about the ATM_BLLI structure. Note that the BLLI layer 2 information is treated as not present if its Layer2Protocol field contains "SAP_FIELD_ABSENT", or wildcard if it contains "SAP_FIELD_ANY". Similarly, the BLLI layer 3 information is treated as not present if its Layer3Protocol field contains "SAP_FIELD_ABSENT", or wildcard if it contains "SAP_FIELD_ANY".
satm_bhli
Identifies the fields in the B-HLI Information Element which are used along with satm_blli to identify an application. See the section below for more details about the ATM_BHLI structure.

Note Satm_bhli is treated as not present if its HighLayerInfoType field contains "SAP_FIELD_ABSENT", or wildcard if it contains "SAP_FIELD_ANY".

For listening sockets, the sockaddr_atm structure is used in bind/WSPBind to register a Service Access Point (SAP) to receive incoming connection requests destined to this SAP. SAP registration is used to match against the SAP specified in an incoming connection request in order to determine which listening socket to receive this request. In current version of this specification, overlapping registration is not allowed. Overlapping registration is defined as having more than one registered SAP to potentially match the SAP specified in any incoming connection request. listen/WSPListen will return the error code WSAEADDRINUSE if the SAP associated with the listening socket overlaps with any currently registered SAPs in the system.

The fields in a SAP to be registered must contain either a valid value, or one of two special manifest constants: "SAP_FIELD_ABSENT", or "SAP_FIELD_ANY". "SAP_FIELD_ABSENT" simply means that this field is not presented as part of a SAP. "SAP_FIELD_ANY" means wildcarding. Note that the requirement of non-overlapping registration does not preclude wildcarding. For example, it is possible to have two registered SAPs which both contain "SAP_FIELD_ANY" in some fields and different values in other fields.

Note The called party ATM number is mandatory, thus the satm_number field cannot contain "SAP_FIELD_ABSENT".

For connecting sockets, the sockaddr_atm structure is used to specify the destination SAP in connect/WSAConnect/WSPConnect for point-to-point connections, and WSAJoinLeaf/WSPJoinLeaf for point-to-multipoint connections. The fields in the destination SAP of a connecting socket must contain either a valid value or "SAP_FIELD_ABSENT", i.e., "SAP_FIELD_ANY" is not allowed. Furthermore, "SAP_FIELD_ABSENT" is not allowed for the satm_number field. The destination SAP is used to match against all the registered SAPs in the destination machine to determine who to forward this connection request to. If each and every field of the destination SAP of an incoming request either equals to the corresponding field of a registered SAP, or the corresponding field contains the "SAP_FIELD_ANY", the listening socket associated with this registered SAP will receive the incoming connection request.

If bind/WSPBind is used on a connecting socket to specify the calling party ATM address, the satm_blli and satm_bhli fields should be ignored and the ones specified in connect/WSAConnect/WSPConnect will be used.


Using the ATM_ADDRESS structure

/*
 *  values used for AddressType in struct ATM_ADDRESS
 */
#define ATM_E164               0x01   /* E.164 addressing scheme */
#define ATM_NSAP               0x02   /* NSAP-style ATM Endsystem Address scheme */
#define ATM_AESA               0x02   /* NSAP-style ATM Endsystem Address scheme */

typedef struct {
    DWORD AddressType;       /* E.164 or NSAP-style ATM Endsystem Address */
    DWORD NumofDigits;       /* number of digits; */
    UCHAR Addr[20];          /* IA5 digits for E164, BCD encoding for NSAP */
                             /* format as defined in the ATM Forum UNI 3.1 */
} ATM_ADDRESS;

For ATM_E164, enter the numbered digits in the same order in which they would be entered on a numeric keypad; i.e., the number digit which would be entered first is located in addr[0]. Digits are coded in IA5 characters. Bit 8 is set to 0.

For ATM_NSAP, code the address using Binary Coded Decimal (BCD) as defined in the ATM Forum UNI 3.1. The NumofDigits field will be ignored in this case, and the NSAP-style address always contains 20 bytes.

A value of "SAP_FIELD_ANY" in AddressType indicates that the satm_number field is a wildcard. There are two more specialized wildcard values: "SAP_FIELD_ANY_AESA_SEL" and "SAP_FIELD_ANY_AESA_REST". "SAP_FIELD_ANY_AESA_SEL" means that this is a NSAP-style ATM Endsystem Address and the selector octet is "wildcarded". "SAP_FIELD_ANY_AESA_REST" means that this is a NSAP-style ATM Endsystem Address and all the octets except for the selector octet are "wildcarded".


The ATM_BLLI structure and associated manifest constants

/*
 *  values used for Layer2Protocol in struct B-LLI
 */
#define BLLI_L2_ISO_1745           0x01   /* Basic mode ISO 1745    */
#define BLLI_L2_Q921               0x02   /* CCITT Rec. Q.921       */
#define BLLI_L2_X25L               0x06   /* CCITT Rec. X.25, link layer              */
#define BLLI_L2_X25M               0x07   /* CCITT Rec. X.25, multilink               */
#define BLLI_L2_ELAPB              0x08   /* Extended LAPB; for half duplex operation */
#define BLLI_L2_HDLC_NRM           0x09   /* HDLC NRM (ISO 4335)                      */
#define BLLI_L2_HDLC_ABM           0x0A   /* HDLC ABM (ISO 4335)                      */
#define BLLI_L2_HDLC_ARM           0x0B   /* HDLC ARM (ISO 4335)                      */
#define BLLI_L2_LLC                0x0C   /* LAN logical link control (ISO 8802/2)    */
#define BLLI_L2_X75                0x0D   /* CCITT Rec. X.75, single link procedure   */
#define BLLI_L2_Q922               0x0E   /* CCITT Rec. Q.922                         */
#define BLLI_L2_USER_SPECIFIED     0x10   /* User Specified                           */
#define BLLI_L2_ISO_7776           0x11   /* ISO 7776 DTE-DTE operation               */

/*
 *  values used for Layer3Protocol in struct B-LLI
 */
#define BLLI_L3_X25                0x06   /* CCITT Rec. X.25, packet layer            */
#define BLLI_L3_ISO_8208           0x07   /* ISO/IEC 8208 (X.25 packet layer for DTE  */
#define BLLI_L3_X223               0x08   /* X.223/ISO 8878                           */
#define BLLI_L3_SIO_8473           0x09   /* ISO/IEC 8473 (OSI connectionless)        */
#define BLLI_L3_T70                0x0A   /* CCITT Rec. T.70 min. network layer       */
#define BLLI_L3_ISO_TR9577         0x0B   /* ISO/IEC TR 9577 Network Layer Protocol ID*/
#define BLLI_L3_USER_SPECIFIED     0x10   /* User Specified                           */

/*
 *  values used for Layer3IPI in struct B-LLI
 */
#define BLLI_L3_IPI_SNAP           0x80   /* IEEE 802.1 SNAP identifier               */
#define BLLI_L3_IPI_IP             0xCC   /* Internet Protocol (IP) identifier        */

typedef struct {
    DWORD Layer2Protocol;                 /* User information layer 2 protocol           */
    DWORD Layer2UserSpecifiedProtocol;    /* User specified layer 2 protocol information */
    DWORD Layer3Protocol;                 /* User information layer 3 protocol           */
    DWORD Layer3UserSpecifiedProtocol;    /* User specified layer 3 protocol information */
    DWORD Layer3IPI;                      /* ISO/IEC TR 9577 Initial Protocol Identifier */
    UCHAR SnapID[5];                      /* SNAP ID consisting of OUI and PID           */
} ATM_BLLI;

Parameters

Layer2Protocol
Identifies the layer 2 protocol. Corresponds to the User information layer 2 protocol field in the B-LLI information element. A value of "SAP_FIELD_ABSENT" indicates that this field is not used, and a value of "SAP_FIELD_ANY" means wildcard.
Layer2UserSpecifiedProtocol
Identifies the user specified layer 2 protocol. Only used if the Layer2Protocol parameter is set to "BLLI_L2_USER_SPECIFIED". The valid values range from 0 to 127. Corresponds to the User specified layer 2 protocol information field in the B-LLI information element.
Layer3Protocol
Identifies the layer 3 protocol. Corresponds to the User information layer 3 protocol field in the B-LLI information element. A value of "SAP_FIELD_ABSENT" indicates that this field is not used, and a value of "SAP_FIELD_ANY" means wildcard.
Layer3UserSpecifiedProtocol
Identifies the user specified layer 3 protocol. Only used if the Layer3Protocol parameter is set to "BLLI_L3_USER_SPECIFIED." The valid values range from 0 to 127. Corresponds to the User specified layer 3 protocol information field in the B-LLI information element.
Layer3IPI
Identifies the layer 3 Initial Protocol Identifier. Only used if the Layer3Protocol parameter is set to "BLLI_L3_ISO_TR9577". Corresponds to the ISO/IEC TR 9577 Initial Protocol Identifier field in the B-LLI information element.
SnapID
Identifies the 802.1 SNAP identifier. Only used if the Layer3Protocol parameter is set to "BLLI_L3_ISO_TR9577" and Layer3IPI is set to "BLLI_L3_IPI_SNAP", indicating an IEEE 802.1 SNAP identifier. Corresponds to the OUI and PID fields in the B-LLI information element.


The ATM_BHLI structure and associated manifest constants

/*
 *  values used for the HighLayerInfoType field in struct ATM_BHLI
 */
#define BHLI_ISO                   0x00   /* ISO                                 */
#define BHLI_UserSpecific          0x01   /* User Specific                       */
#define BHLI_HighLayerProfile      0x02   /* High layer profile (only in UNI3.0) */
#define BHLI_VendorSpecificAppId   0x03   /* Vendor-Specific Application ID      */

typedef struct {
    DWORD HighLayerInfoType;          /* High Layer Information Type      */
    DWORD HighLayerInfoLength;        /* number of bytes in HighLayerInfo */
    UCHAR HighLayerInfo[8];           /* the value dependent on the       */
                                      /*   HighLayerInfoType field        */
} ATM_BHLI;

Parameters

HighLayerInfoType
Identifies the high layer information type field in the B-LLI information element. Note that the type BHLI_HighLayerProfile has been eliminated in UNI 3.1. A value of "SAP_FIELD_ABSENT" indicates that B-HLI is not present, and a value of "SAP_FIELD_ANY" means wildcard.
HighLayerInfoLength
Identifies the number of bytes from 1 to 8 in the HighLayerInfo array. Valid values include 8 for the cases of BHLI_ISO and BHLI_UserSpecific, 4 for BHLI_HighLayerProfile, and 7 for BHLI_VendorSpecificAppId.
HighLayerInfo
Identifies the high layer information field in the B-LLI information element. In the case HighLayerInfoType being BHLI_VendorSpecificAppId, the first three bytes consist of a globally-administered Organizationally Unique Identifier (OUI)(as per IEEE standard 802-1990), followed by a four-byte application identifier, which is administered by the vendor identified by the OUI. Value for the case of BHLI_UserSpecific is user defined and requires bilateral agreement between two end users.


ATM Controls

ATM point-to-point and point-to-multipoint connection setup and teardown are natively supported by the Windows Sockets 2 specification. In fact, Windows Sockets 2 QOS spec and protocol-independent multipoint/multicast mechanisms were designed with ATM in mind, along with other protocols. See section 2.7 and appendix D of the Windows Sockets 2 API specification for Windows Sockets 2 QOS and multipoint support, respectively. Therefore, no ATM specific ioctls need to be introduced in this document.


ATM Function Specifics

Based on the taxonomy defined for Windows Sockets 2 protocol-independent multipoint/multicast schemes, ATM falls into the category of "rooted data" and "rooted control" planes. (See Windows Sockets 2 API specification, Appendix D for more information.) An application acting as the root would create c_root sockets and counterparts running on leaf nodes would utilize c_leaf sockets. The root application will use WSAJoinLeaf to add new leaf nodes. The corresponding applications on the leaf nodes will have set their c_leaf sockets into the listening mode. WSAJoinLeaf with a c_root socket specified will be mapped to the Q.2931 SETUP message (for the first leaf) or ADD PARTY message (for any subsequent leaves).

Note The QOS parameters specified in WSAJoinLeaf for any subsequent leaves should be ignored per the ATM Forum UNI specification.

The leaf-initiated join is not part of the ATM UNI 3.1, but will be supported in the ATM UNI 4.0. Thus WSAJoinLeaf with a c_leaf socket specified will be mapped to the appropriate ATM UNI 4.0 message.

The AAL Parameter and B-LLI negotiation is supported via the modification of the corresponding IEs in the lpSQOS parameter upon the invocation of the condition function specified in WSAAccept.

Note Only certain fields in those two IEs can be modified. See the ATM Forum UNI specification Appendix C and F for details.


ATM-specific QOS Extension

This section describes the protocol-specific QOS structure for ATM, which is contained in the ProviderSpecific.buf field of the QOS structure. Note that the use of this ATM-specific QOS structure is optional by Windows Sockets 2 clients, and the ATM service provider is required to map the generic FLOWSPEC structure to appropriate Q.2931 Information Elements. However, if both the generic FLOWSPEC structure and ATM-specific QOS structure are specified, the value specified in the ATM-specific QOS structure should take precedence should there be any conflicts. See Windows Sockets 2 API specification section 2.7 for more information about the QOS provisions and FLOWSPEC structure.

The protocol-specific QOS structure for ATM is a concatenation of Q.2931 Information Element (IE) structures, which are defined below. If an application omits an IE that UNI 3.x mandates, the service provider should insert a reasonable default value, taking the information in the FLOWSPEC structure into account if applicable.

The handling of repeated IEs is dependent on the IE itself. If an IE is repeated and it is one that is allowed to be repeated per ATM Forum UNI spec then the provider must handle it properly. In this case, order in the list determines preference order, with elements appearing earlier in the list being more preferred. If an IE is repeated and this is not allowed per ATM Forum UNI spec, the provider may either fail the request from the client (the preferred option) or use the last IE of that type found.

Each individual IE structure is formatted in the following fashion and identified by the IEType field:

typedef struct {
    Q2931_IE_TYPE IEType;
    ULONG         IELength;
    UCHAR         IE[1];
} Q2931_IE;

Legal values for the IEType field are defined below:

typedef enum {
    IE_AALParameters,
    IE_TrafficDescriptor,
    IE_BroadbandBearerCapability,
    IE_BHLI,
    IE_BLLI,
    IE_CalledPartyNumber,
    IE_CalledPartySubaddress,
    IE_CallingPartyNumber,
    IE_CallingPartySubaddress,
    IE_Cause,
    IE_QOSClass,
    IE_TransitNetworkSelection,
} Q2931_IE_TYPE;

The IE field is overlaid by a specific IE structure defined below, and the IELength field is the total length in bytes of the IE structure including the IEType and IELength fields. The semantics and legal values for each element of these IE structures are per ATM UNI 3.x specification. "SAP_FIELD_ABSENT" can be used for those elements which are optional for a given IE structure, per ATM UNI 3.x specification.


AAL Parameters

/*
 *  manifest constants for the AALType field in struct AAL_PARAMETERS_IE
 */
typedef enum {
    AALTYPE_5     = 5,   /* AAL 5 */
    AALTYPE_USER  = 16   /* user-defined AAL */
} AAL_TYPE;

/*
 *  values used for the Mode field in struct AAL5_PARAMETERS
 */
#define AAL5_MODE_MESSAGE           0x01
#define AAL5_MODE_STREAMING         0x02

/*
 *  values used for the SSCSType field in struct AAL5_PARAMETERS
 */
#define AAL5_SSCS_NULL              0x00
#define AAL5_SSCS_SSCOP_ASSURED     0x01
#define AAL5_SSCS_SSCOP_NON_ASSURED 0x02
#define AAL5_SSCS_FRAME_RELAY       0x04

typedef struct {
    ULONG ForwardMaxCPCSSDUSize;
    ULONG BackwardMaxCPCSSDUSize;
    UCHAR Mode;                        /* only available in UNI 3.0 */
    UCHAR SSCSType;
} AAL5_PARAMETERS;

typedef struct {
    ULONG UserDefined;
} AALUSER_PARAMETES;

typedef struct {
    AAL_TYPE AALType;
    union {
        AAL5_PARAMETERS     AAL5Parameters;
        AALUSER_PARAMETERS  AALUserParameters;
    } AALSpecificParameters;
} AAL_PARAMETERS_IE;


ATM Traffic Descriptor

This sections lists the ATM Traffic Descriptor.

typedef struct {
    ULONG PeakCellRate_CLP0;
    ULONG PeakCellRate_CLP01;
    ULONG SustainableCellRate_CLP0;
    ULONG SustainableCellRate_CLP01;
    ULONG MaxBurstSize_CLP0;
    ULONG MaxBurstSize_CLP01;
    BOOL  Tagging;
} ATM_TD;

typedef struct {
    ATM_TD Forward;
    ATM_TD Backward;
    BOOL   BestEffort;
} ATM_TRAFFIC_DESCRIPTOR_IE;


Broadband Bearer Capability

This section lists the values used for the Broadband Bearer Capability.

/*
 *  values used for the BearerClass field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define BCOB_A                   0x00   /* Bearer class A           */
#define BCOB_C                   0x03   /* Bearer class C           */
#define BCOB_X                   0x10   /* Bearer class X           */

/*
 *  values used for the TrafficType field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define TT_NOIND                 0x00   /* No indication of traffic type       */
#define TT_CBR                   0x04   /* Constant bit rate                   */
#define TT_VBR                   0x06   /* Variable bit rate                   */

/*
 *  values used for the TimingRequirements field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define TR_NOIND                 0x00   /* No timing requirement indication    */
#define TR_END_TO_END            0x01   /* End-to-end timing required          */
#define TR_NO_END_TO_END         0x02   /* End-to-end timing not required      */

/*
 *  values used for the ClippingSusceptability field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define CLIP_NOT                 0x00   /* Not susceptible to clipping         */
#define CLIP_SUS                 0x20   /* Susceptible to clipping             */

/*
 *  values used for the UserPlaneConnectionConfig field in
 *  struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define UP_P2P                   0x00   /* Point-to-point connection           */
#define UP_P2MP                  0x01   /* Point-to-multipoint connection      */

typedef struct {
    UCHAR BearerClass;
    UCHAR TrafficType;
    UCHAR TimingRequirements;
    UCHAR ClippingSusceptability;
    UCHAR UserPlaneConnectionConfig;
} ATM_BROADBAND_BEARER_CAPABILITY_IE;


Broadband High Layer Information

This section lists the type definition for the broadband high-layer information.

typedef ATM_BHLI ATM_BHLI_IE;


Broadband Lower Layer Information

This section lists the type definition for the broadband lower-layer information.

/*
 *  values used for the Layer2Mode field in struct ATM_BLLI_IE
 */
#define BLLI_L2_MODE_NORMAL         0x40
#define BLLI_L2_MODE_EXT            0x80

/*
 *  values used for the Layer3Mode field in struct ATM_BLLI_IE
 */
#define BLLI_L3_MODE_NORMAL         0x40
#define BLLI_L3_MODE_EXT            0x80

/*
 *  values used for the Layer3DefaultPacketSize field in struct ATM_BLLI_IE
 */
#define BLLI_L3_PACKET_16           0x04
#define BLLI_L3_PACKET_32           0x05
#define BLLI_L3_PACKET_64           0x06
#define BLLI_L3_PACKET_128          0x07
#define BLLI_L3_PACKET_256          0x08
#define BLLI_L3_PACKET_512          0x09
#define BLLI_L3_PACKET_1024         0x0A
#define BLLI_L3_PACKET_2048         0x0B
#define BLLI_L3_PACKET_4096         0x0C

typedef struct {
    DWORD Layer2Protocol;                 /* User information layer 2 protocol           */
    UCHAR Layer2Mode;
    UCHAR Layer2WindowSize;
    DWORD Layer2UserSpecifiedProtocol;    /* User specified layer 2 protocol information */
    DWORD Layer3Protocol;                 /* User information layer 3 protocol           */
    UCHAR Layer3Mode;
    UCHAR Layer3DefaultPacketSize;
    UCHAR Layer3PacketWindowSize;
    DWORD Layer3UserSpecifiedProtocol;    /* User specified layer 3 protocol information */
    DWORD Layer3IPI;                      /* ISO/IEC TR 9577 Initial Protocol Identifier */
    UCHAR SnapID[5];                      /* SNAP ID consisting of OUI and PID           */
} ATM_BLLI_IE;


Called Party Number

This section lists the type definition for called party number.

typedef ATM_ADDRESS ATM_CALLED_PARTY_NUMBER_IE;


Called Party Subaddress

This section lists the type definition for called party subaddress.

typedef ATM_ADDRESS ATM_CALLED_PARTY_SUBADDRESS_IE;


Calling Party Number

This section lists the type definition for calling party number.

/*
 *  values used for the Presentation_Indication field in
 *  struct ATM_CALLING_PARTY_NUMBER_IE
 */
#define PI_ALLOWED                  0x00
#define PI_RESTRICTED               0x40
#define PI_NUMBER_NOT_AVAILABLE     0x80

/*
 *  values used for the Screening_Indicator field in
 *  struct ATM_CALLING_PARTY_NUMBER_IE
 */
#define SI_USER_NOT_SCREENED        0x00
#define SI_USER_PASSED              0x01
#define SI_USER_FAILED              0x02
#define SI_NETWORK                  0x03

typedef struct {
    ATM_ADDRESS ATM_Number;
    UCHAR       Presentation_Indication;
    UCHAR       Screening_Indicator;
} ATM_CALLING_PARTY_NUMBER_IE;


Calling Party Subaddress

This section lists the type definition for calling party subaddress.

typedef ATM_ADDRESS ATM_CALLING_PARTY_SUBADDRESS_IE;


Quality of Service Parameter

This section lists the parameters used for quality of service (QOS).

/*
 *  values used for the QOSClassForward and QOSClassBackward
 *  field in struct ATM_QOS_CLASS_IE
 */
#define QOS_CLASS0                  0x00
#define QOS_CLASS1                  0x01
#define QOS_CLASS2                  0x02
#define QOS_CLASS3                  0x03
#define QOS_CLASS4                  0x04

typedef struct {
    UCHAR QOSClassForward;
    UCHAR QOSClassBackward;
} ATM_QOS_CLASS_IE;


Transit Network Selection

This section lists values used for transit network selection.

/*
 *  values used for the TypeOfNetworkId field in struct ATM_TRANSIT_NETWORK_SELECTION_IE
 */
#define TNS_TYPE_NATIONAL           0x40

/*
 *  values used for the NetworkIdPlan field in struct ATM_TRANSIT_NETWORK_SELECTION_IE
 */
#define TNS_PLAN_CARRIER_ID_CODE    0x01

typedef struct {
    UCHAR TypeOfNetworkId;
    UCHAR NetworkIdPlan;
    UCHAR NetworkIdLength;
    UCHAR NetworkId[1];
} ATM_TRANSIT_NETWORK_SELECTION_IE;


Cause

In addition to all the IEs described above, which could be specified in the ATM-specific QOS structure while calling WSAConnect, there is a Cause IE which can only be used during the call release. Upon disconnecting, Windows Sockets 2 applications can optionally specify this IE as the disconnect data in WSASendDisconnect. The remote party can retrieve this IE via WSARecvDisconnect after receiving the FD_CLOSE notification.

/*
 *  values used for the Location field in struct ATM_CAUSE_IE
 */
#define CAUSE_LOC_USER                      0x00
#define CAUSE_LOC_PRIVATE_LOCAL             0x01
#define CAUSE_LOC_PUBLIC_LOCAL              0x02
#define CAUSE_LOC_TRANSIT_NETWORK           0x03
#define CAUSE_LOC_PUBLIC_REMOTE             0x04
#define CAUSE_LOC_PRIVATE_REMOTE            0x05
#define CAUSE_LOC_INTERNATIONAL_NETWORK     0x06
#define CAUSE_LOC_BEYOND_INTERWORKING       0x0A

/*
 *  values used for the Cause field in struct ATM_CAUSE_IE
 */
#define CAUSE_UNALLOCATED_NUMBER                0x01
#define CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK       0x02
#define CAUSE_NO_ROUTE_TO_DESTINATION           0x03
#define CAUSE_VPI_VCI_UNACCEPTABLE              0x0A
#define CAUSE_NORMAL_CALL_CLEARING              0x10
#define CAUSE_USER_BUSY                         0x11
#define CAUSE_NO_USER_RESPONDING                0x12
#define CAUSE_CALL_REJECTED                     0x15
#define CAUSE_NUMBER_CHANGED                    0x16
#define CAUSE_USER_REJECTS_CLIR                 0x17
#define CAUSE_DESTINATION_OUT_OF_ORDER          0x1B
#define CAUSE_INVALID_NUMBER_FORMAT             0x1C
#define CAUSE_STATUS_ENQUIRY_RESPONSE           0x1E
#define CAUSE_NORMAL_UNSPECIFIED                0x1F
#define CAUSE_VPI_VCI_UNAVAILABLE               0x23
#define CAUSE_NETWORK_OUT_OF_ORDER              0x26
#define CAUSE_TEMPORARY_FAILURE                 0x29
#define CAUSE_ACCESS_INFORMAION_DISCARDED       0x2B
#define CAUSE_NO_VPI_VCI_AVAILABLE              0x2D
#define CAUSE_RESOURCE_UNAVAILABLE              0x2F
#define CAUSE_QOS_UNAVAILABLE                   0x31
#define CAUSE_USER_CELL_RATE_UNAVAILABLE        0x33
#define CAUSE_BEARER_CAPABILITY_UNAUTHORIZED    0x39
#define CAUSE_BEARER_CAPABILITY_UNAVAILABLE     0x3A
#define CAUSE_OPTION_UNAVAILABLE                0x3F
#define CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED   0x41
#define CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS    0x49
#define CAUSE_INVALID_CALL_REFERENCE            0x51
#define CAUSE_CHANNEL_NONEXISTENT               0x52
#define CAUSE_INCOMPATIBLE_DESTINATION          0x58
#define CAUSE_INVALID_ENDPOINT_REFERENCE        0x59
#define CAUSE_INVALID_TRANSIT_NETWORK_SELECTION 0x5B
#define CAUSE_TOO_MANY_PENDING_ADD_PARTY        0x5C
#define CAUSE_AAL_PARAMETERS_UNSUPPORTED        0x5D
#define CAUSE_MANDATORY_IE_MISSING              0x60
#define CAUSE_UNIMPLEMENTED_MESSAGE_TYPE        0x61
#define CAUSE_UNIMPLEMENTED_IE                  0x63
#define CAUSE_INVALID_IE_CONTENTS               0x64
#define CAUSE_INVALID_STATE_FOR_MESSAGE         0x65
#define CAUSE_RECOVERY_ON_TIMEOUT               0x66
#define CAUSE_INCORRECT_MESSAGE_LENGTH          0x68
#define CAUSE_PROTOCOL_ERROR                    0x6F

/*
 *  values used for the Condition portion of the Diagnostics field
 *  in struct ATM_CAUSE_IE, for certain Cause values
 */
#define CAUSE_COND_UNKNOWN                  0x00
#define CAUSE_COND_PERMANENT                0x01
#define CAUSE_COND_TRANSIENT                0x02

/*
 *  values used for the Rejection Reason portion of the Diagnostics field
 *  in struct ATM_CAUSE_IE, for certain Cause values
 */
#define CAUSE_REASON_USER                   0x00
#define CAUSE_REASON_IE_MISSING             0x04
#define CAUSE_REASON_IE_INSUFFICIENT        0x08

/*
 *  values used for the P-U flag of the Diagnostics field
 *  in struct ATM_CAUSE_IE, for certain Cause values
 */
#define CAUSE_PU_PROVIDER                   0x00
#define CAUSE_PU_USER                       0x08

/*
 *  values used for the N-A flag of the Diagnostics field
 *  in struct ATM_CAUSE_IE, for certain Cause values
 */
#define CAUSE_NA_NORMAL                     0x00
#define CAUSE_NA_ABNORMAL                   0x04

typedef struct {
    UCHAR Location;
    UCHAR Cause;
    UCHAR DiagnosticsLength;
    UCHAR Diagnostics[4];
} ATM_CAUSE_IE;


ATM Header File

This section lists the ATM header file.

#ifndef _WS2ATM_H_
#define _WS2ATM_H_

#pragma pack(1)

#define ATMPROTO_AALUSER           0x00   /* User-defined AAL */
#define ATMPROTO_AAL1              0x01   /* AAL 1 */
#define ATMPROTO_AAL2              0x02   /* AAL 2 */
#define ATMPROTO_AAL34             0x03   /* AAL 3/4 */
#define ATMPROTO_AAL5              0x05   /* AAL 5 */

#define SAP_FIELD_ABSENT           0xFFFFFFFE
#define SAP_FIELD_ANY              0xFFFFFFFF
#define SAP_FIELD_ANY_AESA_SEL     0xFFFFFFFA
#define SAP_FIELD_ANY_AESA_REST    0xFFFFFFFB

/*
 *  values used for AddressType in struct ATM_ADDRESS
 */
#define ATM_E164               0x01   /* E.164 addressing scheme */
#define ATM_NSAP               0x02   /* NSAP-style ATM Endsystem Address scheme */
#define ATM_AESA               0x02   /* NSAP-style ATM Endsystem Address scheme */

typedef struct {
    DWORD  AddressType;       /* E.164 or NSAP-style ATM Endsystem Address */
    DWORD  NumofDigits;       /* number of digits; */
    UCHAR  Addr[20];          /* IA5 digits for E164, BCD encoding for NSAP */
                              /* format as defined in the ATM Forum UNI 3.1 */
} ATM_ADDRESS;

/*
 *  values used for Layer2Protocol in B-LLI
 */
#define BLLI_L2_ISO_1745           0x01   /* Basic mode ISO 1745                      */
#define BLLI_L2_Q921               0x02   /* CCITT Rec. Q.921                         */
#define BLLI_L2_X25L               0x06   /* CCITT Rec. X.25, link layer              */
#define BLLI_L2_X25M               0x07   /* CCITT Rec. X.25, multilink               */
#define BLLI_L2_ELAPB              0x08   /* Extended LAPB; for half duplex operation */
#define BLLI_L2_HDLC_NRM           0x09   /* HDLC NRM (ISO 4335)                      */
#define BLLI_L2_HDLC_ABM           0x0A   /* HDLC ABM (ISO 4335)                      */
#define BLLI_L2_HDLC_ARM           0x0B   /* HDLC ARM (ISO 4335)                      */
#define BLLI_L2_LLC                0x0C   /* LAN logical link control (ISO 8802/2)    */
#define BLLI_L2_X75                0x0D   /* CCITT Rec. X.75, single link procedure   */
#define BLLI_L2_Q922               0x0E   /* CCITT Rec. Q.922                         */
#define BLLI_L2_USER_SPECIFIED     0x10   /* User Specified                           */
#define BLLI_L2_ISO_7776           0x11   /* ISO 7776 DTE-DTE operation               */

/*
 *  values used for Layer3Protocol in B-LLI
 */
#define BLLI_L3_X25                0x06   /* CCITT Rec. X.25, packet layer            */
#define BLLI_L3_ISO_8208           0x07   /* ISO/IEC 8208 (X.25 packet layer for DTE  */
#define BLLI_L3_X223               0x08   /* X.223/ISO 8878                           */
#define BLLI_L3_SIO_8473           0x09   /* ISO/IEC 8473 (OSI connectionless)        */
#define BLLI_L3_T70                0x0A   /* CCITT Rec. T.70 min. network layer       */
#define BLLI_L3_ISO_TR9577         0x0B   /* ISO/IEC TR 9577 Network Layer Protocol ID*/
#define BLLI_L3_USER_SPECIFIED     0x10   /* User Specified                           */

/*
 *  values used for Layer3IPI in B-LLI
 */
#define BLLI_L3_IPI_SNAP           0x80   /* IEEE 802.1 SNAP identifier               */
#define BLLI_L3_IPI_IP             0xCC   /* Internet Protocol (IP) identifier        */

typedef struct {
    DWORD Layer2Protocol;                 /* User information layer 2 protocol           */
    DWORD Layer2UserSpecifiedProtocol;    /* User specified layer 2 protocol information */
    DWORD Layer3Protocol;                 /* User information layer 3 protocol           */
    DWORD Layer3UserSpecifiedProtocol;    /* User specified layer 3 protocol information */
    DWORD Layer3IPI;                      /* ISO/IEC TR 9577 Initial Protocol Identifier */
    UCHAR SnapID[5];                      /* SNAP ID consisting of OUI and PID           */
} ATM_BLLI;

/*
 *  values used for the HighLayerInfoType field in ATM_BHLI
 */
#define BHLI_ISO                   0x00   /* ISO                                 */
#define BHLI_UserSpecific          0x01   /* User Specific                       */
#define BHLI_HighLayerProfile      0x02   /* High layer profile (only in UNI3.0) */
#define BHLI_VendorSpecificAppId   0x03   /* Vendor-Specific Application ID      */

typedef struct {
    DWORD HighLayerInfoType;          /* High Layer Information Type      */
    DWORD HighLayerInfoLength;        /* number of bytes in HighLayerInfo */
    UCHAR HighLayerInfo[8];           /* the value dependent on the       */
                                      /*   HighLayerInfoType field        */
} ATM_BHLI;

struct sockaddr_atm {
    u_short satm_family;              /* address family should be AF_ATM  */
    ATM_ADDRESS satm_number;          /* ATM address                      */
    ATM_BLLI satm_blli;               /* B-LLI                            */
    ATM_BHLI satm_bhli;               /* B-HLI                            */
};

typedef enum {
    IE_AALParameters,
    IE_TrafficDescriptor,
    IE_BroadbandBearerCapability,
    IE_BHLI,
    IE_BLLI,
    IE_CalledPartyNumber,
    IE_CalledPartySubaddress,
    IE_CallingPartyNumber,
    IE_CallingPartySubaddress,
    IE_Cause,
    IE_QOSClass,
    IE_TransitNetworkSelection,
} Q2931_IE_TYPE;

typedef struct {
    Q2931_IE_TYPE IEType;
    ULONG         IELength;
    UCHAR         IE[1];
} Q2931_IE;

/*
 *  manifest constants for the AALType field in struct AAL_PARAMETERS_IE
 */
typedef enum {
    AALTYPE_5     = 5,   /* AAL 5 */
    AALTYPE_USER  = 16,  /* user-defined AAL */
} AAL_TYPE;

/*
 *  values used for the Mode field in struct AAL5_PARAMETERS
 */
#define AAL5_MODE_MESSAGE           0x01
#define AAL5_MODE_STREAMING         0x02

/*
 *  values used for the SSCSType field in struct AAL5_PARAMETERS
 */
#define AAL5_SSCS_NULL              0x00
#define AAL5_SSCS_SSCOP_ASSURED     0x01
#define AAL5_SSCS_SSCOP_NON_ASSURED 0x02
#define AAL5_SSCS_FRAME_RELAY       0x04

typedef struct {
    ULONG ForwardMaxCPCSSDUSize;
    ULONG BackwardMaxCPCSSDUSize;
    UCHAR Mode;                        /* only available in UNI 3.0 */
    UCHAR SSCSType;
} AAL5_PARAMETERS;

typedef struct {
    ULONG UserDefined;
} AALUSER_PARAMETERS;

typedef struct {
    AAL_TYPE AALType;
    union {
        AAL5_PARAMETERS     AAL5Parameters;
        AALUSER_PARAMETERS  AALUserParameters;
    } AALSpecificParameters;
} AAL_PARAMETERS_IE;

typedef struct {
    ULONG PeakCellRate_CLP0;
    ULONG PeakCellRate_CLP01;
    ULONG SustainableCellRate_CLP0;
    ULONG SustainableCellRate_CLP01;
    ULONG MaxBurstSize_CLP0;
    ULONG MaxBurstSize_CLP01;
    BOOL  Tagging;
} ATM_TD;

typedef struct {
    ATM_TD Forward;
    ATM_TD Backward;
    BOOL   BestEffort;
} ATM_TRAFFIC_DESCRIPTOR_IE;

/*
 *  values used for the BearerClass field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define BCOB_A                   0x01   /* Bearer class A                      */
#define BCOB_C                   0x03   /* Bearer class C                      */
#define BCOB_X                   0x10   /* Bearer class X                      */

/*
 *  values used for the TrafficType field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define TT_NOIND                 0x00   /* No indication of traffic type       */
#define TT_CBR                   0x04   /* Constant bit rate                   */
#define TT_VBR                   0x06   /* Variable bit rate                   */

/*
 *  values used for the TimingRequirements field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define TR_NOIND                 0x00   /* No timing requirement indication    */
#define TR_END_TO_END            0x01   /* End-to-end timing required          */
#define TR_NO_END_TO_END         0x02   /* End-to-end timing not required      */

/*
 *  values used for the ClippingSusceptability field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define CLIP_NOT                 0x00   /* Not susceptible to clipping         */
#define CLIP_SUS                 0x20   /* Susceptible to clipping             */

/*
 *  values used for the UserPlaneConnectionConfig field in
 *  struct ATM_BROADBAND_BEARER_CAPABILITY_IE
 */
#define UP_P2P                   0x00   /* Point-to-point connection           */
#define UP_P2MP                  0x01   /* Point-to-multipoint connection      */

typedef struct {
    UCHAR BearerClass;
    UCHAR TrafficType;
    UCHAR TimingRequirements;
    UCHAR ClippingSusceptability;
    UCHAR UserPlaneConnectionConfig;
} ATM_BROADBAND_BEARER_CAPABILITY_IE;

typedef ATM_BHLI ATM_BHLI_IE;

/*
 *  values used for the Layer2Mode field in struct ATM_BLLI_IE
 */
#define BLLI_L2_MODE_NORMAL         0x40
#define BLLI_L2_MODE_EXT            0x80

/*
 *  values used for the Layer3Mode field in struct ATM_BLLI_IE
 */
#define BLLI_L3_MODE_NORMAL         0x40
#define BLLI_L3_MODE_EXT            0x80

/*
 *  values used for the Layer3DefaultPacketSize field in struct ATM_BLLI_IE
 */
#define BLLI_L3_PACKET_16           0x04
#define BLLI_L3_PACKET_32           0x05
#define BLLI_L3_PACKET_64           0x06
#define BLLI_L3_PACKET_128          0x07
#define BLLI_L3_PACKET_256          0x08
#define BLLI_L3_PACKET_512          0x09
#define BLLI_L3_PACKET_1024         0x0A
#define BLLI_L3_PACKET_2048         0x0B
#define BLLI_L3_PACKET_4096         0x0C

typedef struct {
    DWORD Layer2Protocol;                 /* User information layer 2 protocol           */
    UCHAR Layer2Mode;
    UCHAR Layer2WindowSize;
    DWORD Layer2UserSpecifiedProtocol;    /* User specified layer 2 protocol information */
    DWORD Layer3Protocol;                 /* User information layer 3 protocol           */
    UCHAR Layer3Mode;
    UCHAR Layer3DefaultPacketSize;
    UCHAR Layer3PacketWindowSize;
    DWORD Layer3UserSpecifiedProtocol;    /* User specified layer 3 protocol information */
    DWORD Layer3IPI;                      /* ISO/IEC TR 9577 Initial Protocol Identifier */
    UCHAR SnapID[5];                      /* SNAP ID consisting of OUI and PID           */
} ATM_BLLI_IE;

typedef ATM_ADDRESS ATM_CALLED_PARTY_NUMBER_IE;

typedef ATM_ADDRESS ATM_CALLED_PARTY_SUBADDRESS_IE;

/*
 *  values used for the Presentation_Indication field in
 *  struct ATM_CALLING_PARTY_NUMBER_IE
 */
#define PI_ALLOWED                  0x00
#define PI_RESTRICTED               0x40
#define PI_NUMBER_NOT_AVAILABLE     0x80

/*
 *  values used for the Screening_Indicator field in
 *  struct ATM_CALLING_PARTY_NUMBER_IE
 */
#define SI_USER_NOT_SCREENED        0x00
#define SI_USER_PASSED              0x01
#define SI_USER_FAILED              0x02
#define SI_NETWORK                  0x03

typedef struct {
    ATM_ADDRESS ATM_Number;
    UCHAR       Presentation_Indication;
    UCHAR       Screening_Indicator;
} ATM_CALLING_PARTY_NUMBER_IE;

typedef ATM_ADDRESS ATM_CALLING_PARTY_SUBADDRESS_IE;

/*
 *  values used for the Location field in struct ATM_CAUSE_IE
 */
#define CAUSE_LOC_USER                      0x00
#define CAUSE_LOC_PRIVATE_LOCAL             0x01
#define CAUSE_LOC_PUBLIC_LOCAL              0x02
#define CAUSE_LOC_TRANSIT_NETWORK           0x03
#define CAUSE_LOC_PUBLIC_REMOTE             0x04
#define CAUSE_LOC_PRIVATE_REMOTE            0x05
#define CAUSE_LOC_INTERNATIONAL_NETWORK     0x06
#define CAUSE_LOC_BEYOND_INTERWORKING       0x0A

/*
 *  values used for the Cause field in struct ATM_CAUSE_IE
 */
#define CAUSE_UNALLOCATED_NUMBER                0x01
#define CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK       0x02
#define CAUSE_NO_ROUTE_TO_DESTINATION           0x03
#define CAUSE_VPI_VCI_UNACCEPTABLE              0x0A
#define CAUSE_NORMAL_CALL_CLEARING              0x10
#define CAUSE_USER_BUSY                         0x11
#define CAUSE_NO_USER_RESPONDING                0x12
#define CAUSE_CALL_REJECTED                     0x15
#define CAUSE_NUMBER_CHANGED                    0x16
#define CAUSE_USER_REJECTS_CLIR                 0x17
#define CAUSE_DESTINATION_OUT_OF_ORDER          0x1B
#define CAUSE_INVALID_NUMBER_FORMAT             0x1C
#define CAUSE_STATUS_ENQUIRY_RESPONSE           0x1E
#define CAUSE_NORMAL_UNSPECIFIED                0x1F
#define CAUSE_VPI_VCI_UNAVAILABLE               0x23
#define CAUSE_NETWORK_OUT_OF_ORDER              0x26
#define CAUSE_TEMPORARY_FAILURE                 0x29
#define CAUSE_ACCESS_INFORMAION_DISCARDED       0x2B
#define CAUSE_NO_VPI_VCI_AVAILABLE              0x2D
#define CAUSE_RESOURCE_UNAVAILABLE              0x2F
#define CAUSE_QOS_UNAVAILABLE                   0x31
#define CAUSE_USER_CELL_RATE_UNAVAILABLE        0x33
#define CAUSE_BEARER_CAPABILITY_UNAUTHORIZED    0x39
#define CAUSE_BEARER_CAPABILITY_UNAVAILABLE     0x3A
#define CAUSE_OPTION_UNAVAILABLE                0x3F
#define CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED   0x41
#define CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS    0x49
#define CAUSE_INVALID_CALL_REFERENCE            0x51
#define CAUSE_CHANNEL_NONEXISTENT               0x52
#define CAUSE_INCOMPATIBLE_DESTINATION          0x58
#define CAUSE_INVALID_ENDPOINT_REFERENCE        0x59
#define CAUSE_INVALID_TRANSIT_NETWORK_SELECTION 0x5B
#define CAUSE_TOO_MANY_PENDING_ADD_PARTY        0x5C
#define CAUSE_AAL_PARAMETERS_UNSUPPORTED        0x5D
#define CAUSE_MANDATORY_IE_MISSING              0x60
#define CAUSE_UNIMPLEMENTED_MESSAGE_TYPE        0x61
#define CAUSE_UNIMPLEMENTED_IE                  0x63
#define CAUSE_INVALID_IE_CONTENTS               0x64
#define CAUSE_INVALID_STATE_FOR_MESSAGE         0x65
#define CAUSE_RECOVERY_ON_TIMEOUT               0x66
#define CAUSE_INCORRECT_MESSAGE_LENGTH          0x68
#define CAUSE_PROTOCOL_ERROR                    0x6F

/*
 *  values used for the Condition portion of the Diagnostics field
 *  in struct ATM_CAUSE_IE, for certain Cause values
 */
#define CAUSE_COND_UNKNOWN                  0x00
#define CAUSE_COND_PERMANENT                0x01
#define CAUSE_COND_TRANSIENT                0x02

/*
 *  values used for the Rejection Reason portion of the Diagnostics field
 *  in struct ATM_CAUSE_IE, for certain Cause values
 */
#define CAUSE_REASON_USER                   0x00
#define CAUSE_REASON_IE_MISSING             0x04
#define CAUSE_REASON_IE_INSUFFICIENT        0x08

/*
 *  values used for the P-U flag of the Diagnostics field
 *  in struct ATM_CAUSE_IE, for certain Cause values
 */
#define CAUSE_PU_PROVIDER                   0x00
#define CAUSE_PU_USER                       0x08

/*
 *  values used for the N-A flag of the Diagnostics field
 *  in struct ATM_CAUSE_IE, for certain Cause values
 */
#define CAUSE_NA_NORMAL                     0x00
#define CAUSE_NA_ABNORMAL                   0x04

typedef struct {
    UCHAR Location;
    UCHAR Cause;
    UCHAR DiagnosticsLength;
    UCHAR Diagnostics[4];
} ATM_CAUSE_IE;

/*
 *  values used for the QOSClassForward and QOSClassBackward
 *  field in struct ATM_QOS_CLASS_IE
 */
#define QOS_CLASS0                  0x00
#define QOS_CLASS1                  0x01
#define QOS_CLASS2                  0x02
#define QOS_CLASS3                  0x03
#define QOS_CLASS4                  0x04

typedef struct {
    UCHAR QOSClassForward;
    UCHAR QOSClassBackward;
} ATM_QOS_CLASS_IE;

/*
 *  values used for the TypeOfNetworkId field in struct ATM_TRANSIT_NETWORK_SELECTION_IE
 */
#define TNS_TYPE_NATIONAL           0x40

/*
 *  values used for the NetworkIdPlan field in struct ATM_TRANSIT_NETWORK_SELECTION_IE
 */
#define TNS_PLAN_CARRIER_ID_CODE    0x01

typedef struct {
    UCHAR TypeOfNetworkId;
    UCHAR NetworkIdPlan;
    UCHAR NetworkIdLength;
    UCHAR NetworkId[1];
} ATM_TRANSIT_NETWORK_SELECTION_IE;

#pragma pack()

#endif   /* _WS2ATM_H_ */


SSL Security Protocol

This section presents protocol information for using the secure sockets layer.

  • SSL Introduction
  • SSL Overview
  • SSL Data Structures
  • SSL Controls
  • SSL Function Specifics
  • SSL Header File


SSL Introduction

This section covers extensions to Windows Sockets 2 that are specific to the Secure Sockets Layer security protocol (SSL). It also describes aspects of base Windows Sockets 2 functions that require special consideration or which may exhibit unique behavior when using SSL.

Network security has become a major consideration in recent times as the scope of networks and their uses continues to grow and expand into the commercial world. Application users and developers want to be assured that their data is private and that they are communicating with the party they intended to. The Secure Sockets Layer (SSL) protocol is intended to address these needs.

Windows Sockets 2's WOSA architecture allows any number of underlying transport protocols to be accessed by applications. While SSL is not itself a complete transport protocol, it is designed to work in conjunction with existing transports that offer reliable, connection-oriented services. From an application's perspective, the addition of SSL causes additional entries to be returned in the WSAEnumProtocols function. These additional entries are identical to the underlying transport protocol entries (e.g. TCP or SPX), but are distinguished by having SSL indicated in the iSecurityScheme field of the WSAPROTOCOL_INFO struct. Having discovered and selected a transport that offers SSL security, the application creates sockets and sends data over them in exactly the same manner as is done for the underlying transport without security. Through this mechanism application developers are able to take advantage of security provisions without having to make extensive modifications to their applications.


SSL Overview

This section describes how an applications developer can discover and effectively utilize transports that have been enhanced with the SSL security protocol. We begin by providing some background information which is necessary to explain the goals and techniques which are integral in any security discussion.


Public-Key Cryptography

For many years, private encrypted messages were communicated between two or more users using keys that are shared among them. Under this model, any two users wishing to communicate privately need to establish a "secure" or protected channel of some kind to share the secret key. This traditional model for cryptography introduces many complications from key management point of view since each user would have to keep numerous secret keys to be used for communicating with all the needed users.

In 1977, the concept of public-key cryptography was invented where two parties can communicate privately without the need to share any secrets. Each party establishes a key-pair, one private key and one public key. The public key, as the name implies, is published to all nodes on a network and is used to encrypt messages to the node. The private key performs the inverse operation and enables the receiving node to decrypt the messages. The private key never leaves the node that "owns" it. This model for private communications simplifies the key management problem to a great extent.

Public-key cryptography can also be used to exchange a secret key between two (or more) nodes without having to communicate any secrets. But, perhaps the most prevalent application for public-key cryptography is a technology referred to as "digital signatures." This technology allows nodes to sign documents or messages using the private key allowing all other nodes to verify the signature using the published public key. The mathematics of public-key cryptosystems make it possible for one node to create a signature for a particular message, allowing others to verify the signature while ensuring that "forging" someone else's signature is computationally not feasible.

The only issue left with the above model for public-key cryptography is the following question:

Why should one believe that a published public key actually belongs to a given user?

This question can be answered using the notion of a digital certificate. The digital certificate of a user is a message composed of the name and other information about the user together with the user's public key. This entire message is digitally signed by an authority that is known to many users and that has the capacity of verifying the identity of a user. A user generates a public-private keypair, safely stores the private key and takes the public key to an authority with proof of identity. The authority generates a digital signature for the user and hands back a digital certificate. The certificate can then be published in a directory or attached to any message being signed by the user. Any other user can then verify the signature of the user using the attached certificate while ensuring the authenticity of the user's identity.

The RSA public-key cryptosystem is the most commonly used in commercial applications and systems. It provides capability for both encryption/decryption operations as well as digital signature and verification operations. The X.509 standard defines a format for digital certificates using the RSA algorithm which SSL supports.

It is also important to note that for performance reasons, public key encryption and decryption is usually constrained to signature applications and encryption of short data blocks such as data encryption keys. Traditional symmetric-key encryption algorithms are usually used for bulk data encryption. SSL supports a variety of symmetric-key algorithms including the DES standard and exportable versions of RC2 and RC4. Refer to the SSL specification document for a complete list of the supported encryption algorithms.


The Secure Sockets Layer Protocol (SSL)

SSL operates by layering a security protocol on top of an underlying reliable connection-oriented transport protocol. The combined protocol establishes a connection with a remote host and then performs a handshake between the two nodes to establish a secure session. Once the security handshake is complete, the protocol then encrypts and authenticates data sent from the local host and decrypts and verifies data received from the remote host. This will all be done in a manner transparent to the application utilizing the SSL protocol.

Using this technology, an application developer can quickly convert a client or a server to provide a variety of security functions. By virtue of this technology being accessible using the Windows Sockets 2.0 API, an end-user application developer can easily provide very strong security within an application. The application can simply enumerate the protocols supported by the system and if any of them provides SSL security, security can be enabled on arbitrary sockets.


Discovering and Using SSL-Enabled Transports

As mentioned previously, application programmers use the standard Windows Sockets 2 protocol enumeration method to discover SSL-enabled transports. Invoking WSAEnumProtocols returns a buffer filled with WSAPROTOCOL_INFO structs, with one such struct for each available transport protocol. Transports which have been enhanced with SSL capabilities have this indicated in the iSecurityScheme field of their WSAPROTOCOL_INFO struct. This field will contain the value:

SECURITY_PROTOCOL_SSL


Using SSL-Enabled Sockets

SSL works with the underlying transport protocol in such a manner as to be largerly invisible to the application. Socket creation, connection establishment and data transfers are all invoked in the usual manner. The SSL protocol injects extra steps in the connection sequence so that its security handshake can occur, but this does not require any overt action on the application's part. Similarly, send and receive operations cause data to be encrypted and decrypted in a transparent fashion.


SSL Data Structures

SSL data structures are introduced along with the ioctl's that they are used in.


SSL Controls

All SSL controls make use of the WSAIoctl function, with a set of dwIoControlCode values that are specific to SSL. The values for the dwIoControlCode are defined as follows:

/*
** This value is the SSL protocol tag and WSAIoctl dwIoControlCode
** "T" value.
*/
#define _SO_SSL                ((2L << 27) | (0x73L << 16))

/*
** These values are used to form the WSAIoctl dwIoControlCode
** "Code" value.
*/
#define _SO_SSL_FLAGS               0x01
#define _SO_SSL_CIPHERS             0x02
#define _SO_SSL_CLIENT              0x03
#define _SO_SSL_SERVER              0x04
#define _SO_SSL_AUTH_CERT_HOOK      0x08
#define _SO_SSL_RSA_ENCRYPT_HOOK    0x10
#define _SO_SSL_RSA_DECRYPT_HOOK    0x20

/*
** Actual SSL Ioctl commands
*/
#define SO_SSL_GET_FLAGS   (IOC_IN |_SO_SSL|_SO_SSL_FLAGS)
#define SO_SSL_SET_FLAGS   (IOC_OUT|_SO_SSL|_SO_SSL_FLAGS)
#define SO_SSL_GET_CIPHERS (IOC_IN |_SO_SSL|_SO_SSL_CIPHERS)
#define SO_SSL_SET_CIPHERS (IOC_OUT|_SO_SSL|_SO_SSL_CIPHERS)
#define SO_SSL_GET_CLIENT  (IOC_IN |_SO_SSL|_SO_SSL_CLIENT)
#define SO_SSL_SET_CLIENT  (IOC_OUT|_SO_SSL|_SO_SSL_CLIENT)
#define SO_SSL_GET_SERVER  (IOC_IN |_SO_SSL|_SO_SSL_SERVER)
#define SO_SSL_SET_SERVER  (IOC_OUT|_SO_SSL|_SO_SSL_SERVER)
#define SO_SSL_GET_AUTH_CERT_HOOK
    (IOC_IN |_SO_SSL|_SO_SSL_AUTH_CERT_HOOK)
#define SO_SSL_SET_AUTH_CERT_HOOK        (IOC_OUT|_SO_SSL|_SO_SSL_AUTH_CERT_HOOK)
#define SO_SSL_GET_RSA_ENCRYPT_HOOK
    (IOC_IN |_SO_SSL|_SO_SSL_RSA_ENCRYPT_HOOK)
#define SO_SSL_SET_RSA_ENCRYPT_HOOK      (IOC_OUT|_SO_SSL|_SO_SSL_RSA_ENCRYPT_HOOK)
#define SO_SSL_GET_RSA_DECRYPT_HOOK
    (IOC_IN |_SO_SSL|_SO_SSL_RSA_DECRYPT_HOOK)
#define SO_SSL_SET_RSA_DECRYPT_HOOK      (IOC_OUT|_SO_SSL|_SO_SSL_RSA_DECRYPT_HOOK)


SO_SSL_GET_FLAGS/SO_SSL_SET_FLAGS

This WSAIoctl command is used to get/set the SSL flags associated with the socket. The lpvInBuffer points to a "WORD". The following flags exist:

#define SO_SSL_ENABLE               0x0001
       #define SO_SSL_SERVER               0x0002
       #define SO_SSL_AUTH_CLIENT          0x0004
       #define SO_SSL_ACCEPT_WEAK          0x0008

The flags are set using the SO_SSL_SET_FLAGS command, while the status of the flags can be queried using the SO_SSL_GET_FLAGS command.

Setting the SO_SSL_ENABLE flag enables security on the socket. If this is done after a connection has already been established, then the SSL handshake protocol is performed before the next byte of data is transferred.

The SO_SSL_SERVER flag, when set, indicates that the socket is to be configured for server operation. In addition, the SO_SSL_AUTH_CLIENT flag indicates that the server will authenticate the client.

The SO_SSL_ACCEPT_WEAK flag, when set, instructs SSL to accept weakly checked certificates.

Strong certificate checking means that the SSL implementation has contacted the certificate issuer online and verified the validity of the certificate. Weak certificate checking means that no online check was performed.


SO_SSL_GET_CIPHERS/SO_SSL_SET_CIPHERS

This WSAIoctl command is used to get/set the privacy ciphers that SSL should attempt to use for the socket. The lpvInBuffer points to the following structure:

struct sslcipheropts {
    int n;
    char specs[3];         /* 3 bytes per n */
};

The value n specifies the number of ciphers (not the number of bytes of ciphers) and specs is an array of 3 byte values that contain the cipher specs. When SO_SSL_GET_CIPHERS is used, the structure is filled in with the ciphers that are supported by the socket. If WSAIoctl with SO_SSL_GET_CIPHERS is called before any changes are made to the socket via SO_SSL_SET_CIPHERS then the value returned will represent the underlying implementations abilities. If SO_SSL_SET_CIPHERS is used then the values are used as a replacement for the built in ciphers for the given socket.

For SO_SSL_SET_CIPHERS, the error EINVAL will be returned if a cipher is specified that is not supported by the implementation. The legal values for the ciphers specs are defined in the SSL specification document.


SO_SSL_GET_CLIENT/SO_SSL_SET_CLIENT

This WSAIoctl command is used to get/set the client data that SSL will use for the socket. The lpvInBuffe points to the following structure:

struct sslclientopts {
    char *cert;
    int certlen;
    time_t sidtimeout;
    int32 sidentries;
    char *siddir;
};

cert and certlen are used to define the clients certificate. sidtimeout specifies the number of seconds that session-id's are allowed to live. sidentries defines the maximum number of entries to keep in the session-id cache. siddir defines the location of the temporary file used to hold the session-id cache when a temporary file is needed by the implementation.

The SSL implementation requires and guarantees MT-safe access to the session-id cache.


SO_SSL_GET_SERVER/SO_SSL_SET_SERVER

This WSAIoctl command is used to get/set the server data that SSL will use for the socket. The lpvInBuffer points to the following structure:

struct sslserveropts {
    char *cert;
    int certlen;
    time_t sidtimeout;
    int32 sidentries;
    char *siddir;
};

cert and certlen are used to define the servers certificate. sidtimeout specifies the number of seconds that session-id's are allowed to live. sidentries defines the maximum number of entries to keep in the session-id cache. siddir defines the location of the temporary file used to hold the session-id cache when a temporary file is needed by the implementation.

The SSL implementation requires and guarantees MT-safe access to the session-id cache.


SO_SSL_GET_AUTH_CERT_HOOK/SO_SSL_SET_AUTH_CERT_HOOK

This WSAIoctl command is used to get/set the certificate authentication hook that SSL will use for the socket. The lpvInBuffer points to the following structure:

struct sslauthcertopts {
    int type;
    int (*func)(void *arg, char *cert, int len);
    void *arg;
};

The SSL implementation will invoke the function with the supplied argument when a certificate arrives (either for server or client authentication). Only certificates of type will be authenticated using this function (see the SSL specification for a list of the supported certificate types). If no function exists for a given certificate type presented to the SSL implementation, the connection/handshake attempt will fail. Otherwise, the function authenticates the certificate and returns one of the following values:

#define SSL_ACH_OK                 0
    #define SSL_ACH_WEAK_OK            1
    #define SSL_ACH_SHORT_DATA         2
    #define SSL_ACH_LONG_DATA          3
    #define SSL_ACH_BAD_DATA           4
     #define SSL_ACH_BAD_SIG           5
    #define SSL_ACH_CERT_EXPIRED       6

The SSL_ACH_OK value is returned when the certificate is good (the signature and validity periods are acceptable) and when the certificate has been verified through some external mechanism (for example, an online check with a certificate authority). The SSL_ACH_WEAK_OK value is returned under the same circumstances, except that no online verification has been performed.

The remaining values represent the kind of error conditions that might occur during certificate verification. SSL_ACH_BAD_DATA is returned when the data presented is improperly formatted. SSL_ACH_BAD_SIG is returned if the signature check fails. SSL_ACH_CERT_EXPIRED is returned if the certificate has expired.


SO_SSL_RSA_ENCRYPT_HOOK

This WSAIoctl command is used to get/set the RSA encryption hook that SSL will use for the socket. The lpvInBuffer points to the following structure:

struct sslrsaencrypthook {
    int (*func)(void *arg, int blockType, char *dest, int *destlen,
    char *src, int srclen);
    void *arg;
};

This hook is used when the SSL implementation requires an RSA private or public key encryption. The blockType determines if the operation is a private or public key operation (only block types 0x01 and 0x02 are used by SSL; see PKCS#1 for more information). The dest and destlen values are used to return the encryption results. destlen is an input/output parameter with the input value defining the maximum storage area available at dest, and the output value containing the actual stored length of the encryption results. The src and srclen values define the input data. The following values are returned by the hook:

#define SSL_REH_OK                0
    #define SSL_REH_BAD_TYPE          1
    #define SSL_REH_BAD_LEN           2

SSL_REH_OK is returned if the encryption succeded. SSL_REH_BAD_TYPE is returned if the blockType value is unacceptable. SSL_REH_BAD_LEN is returned if the srclen is too large to be encrypted in a single encryption, or if the dstlen value is too small to hold the encryption results.


SO_SSL_RSA_DECRYPT_HOOK

This WSAIoctl command is used to get/set the RSA decryption hook that SSL will use for the socket. The lpvInBuffer points to the following structure:

struct sslrsadecrypthook {
    int (*func)(void *arg, int blockType, char *dest, int *destlen,
    char *src, int srclen);
    void *arg;
};

This hook is used when the SSL implementation requires an RSA private or public key decryption. The blockType determines if the operation is a private or public key operation (only block types 0x01 and 0x02 are used by SSL; see PKCS#1 for more information). The dest and destlen values are used to return the decryption results. destlen is an input/output parameter with the input value defining the maximum storage area available at dest, and the output value containing the actual stored length of the decryption results. The src and srclen values define the input data. The following values are returned by the hook:

#define SSL_RDH_OK           0
    #define SSL_RDH_BAD_TYPE     1
    #define SSL_RDH_BAD_LEN      2

SSL_RDH_OK is returned if the decryption succeeded. SSL_RDH_BAD_TYPE is returned if the blockType value is unacceptable. SSL_RDH_BAD_LEN is returned if the srclen doesn't match the key's modulus length, or if the dstlen value is too small to hold the decryption results.


SSL Function Specifics

Information to be provided at a later release.


SSL Header File

Information to be provided at a later release.


Information for Wireless Networking

Editors Note: The Windows Sockets 2 wireless group is currently re-evaluating the planned definition of the NetDev device control API as a means to meet the requirements of wireless-aware applications. Other alternatives such as Desktop Management Interface (DMI) are under active consideration. The material which appeared here in the previous edition of this Annex has been elided until such time as these discussions produce a clear direction.

This section covers extensions to Windows Sockets 2 that are specific to the use of wireless networks. It also describes aspects of base Windows Sockets 2 functions that require special consideration or which may exhibit unique behavior when using such networks.


Windows Sockets and TAPI Integration

Editors Note: After extensive consultations between experts on both Windows Sockets and TAPI, a general consensus has emerged that networking applications can best meet their telephony needs by utilizing the Remote Network Access (also known as Remote Access Services) facilities of Windows ™ instead of directly accessing the Windows Telephony API (TAPI). Therefore, the material which appeared here in previous versions of the Annex has been elided.

This section describes mechanisms for using the Windows Sockets interface in conjunction with the TAPI. It was prepared by the Windows Sockets Forum's Connection Oriented Media functionality group.


RSVP

The Resource Reservation Protocol (RSVP) implementation of the Windows Sockets 2 Protocol-Specific Annex, found at ftp://ftp.microsoft.com/bussys/winsock/winsock2/wsanx203.doc, is not supported by Microsoft. For information on how Microsoft implements RSVP for quality of service (QOS), please refer to the Generic Quality of Service (GQOS) documentation in the Platform SDK.


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

Remedy: Insert the MSDN Library CD into the CD-ROM drive.