WSPStartup, fonction (ws2spi.h)

La fonction WSPStartup lance l’utilisation d’une interface SPI (Windows Sockets Service Provider Interface) par un client.

Syntaxe

int WSPStartup(
  [in]  WORD                wVersionRequested,
  [out] LPWSPDATA           lpWSPData,
  [in]  LPWSAPROTOCOL_INFOW lpProtocolInfo,
  [in]  WSPUPCALLTABLE      UpcallTable,
  [out] LPWSPPROC_TABLE     lpProcTable
);

Paramètres

[in] wVersionRequested

La version la plus élevée de Windows Sockets SPI prend en charge que l’appelant peut utiliser. L’octet d’ordre élevé spécifie le numéro de version mineure (révision) ; l’octet d’ordre inférieur spécifie le numéro de version principale.

[out] lpWSPData

Pointeur vers une structure de données WSPDATA qui reçoit des informations sur le fournisseur de services Windows Sockets.

[in] lpProtocolInfo

Pointeur vers une structure WSAProtocol_Info qui définit les caractéristiques du protocole souhaité. Cela est particulièrement utile lorsqu’une DLL de fournisseur unique est capable d’instancier plusieurs fournisseurs de services différents.

[in] UpcallTable

La table de distribution d’appel upcall Winsock 2 DLL (Ws2_32.dll) transmise dans une structure WSPUpCallTable .

[out] lpProcTable

Pointeur vers la table des pointeurs de fonction SPI. Cette table est retournée en tant que structure WSPProc_Table .

Valeur retournée

La fonction WSPStartup retourne zéro en cas de réussite. Sinon, il retourne l’un des codes d’erreur répertoriés ci-dessous.

Code d'erreur Signification
WSASYSNOTREADY
Le sous-système réseau n’est pas disponible. Cette erreur est retournée si l’implémentation de Windows Sockets ne peut pas fonctionner pour le moment, car le système sous-jacent qu’elle utilise pour fournir des services réseau n’est actuellement pas disponible.
WSAVERNOTSUPPORTED
La version Winsock.dll est hors limites. Cette erreur est retournée si la version de la prise en charge SPI de Windows Sockets demandée n’est pas fournie par ce fournisseur de services Windows Sockets particulier.
WSAEINPROGRESS
Une opération windows sockets 1.1 bloquante est en cours.
WSAEPROCLIM
Une limite du nombre de tâches prises en charge par l’implémentation de Windows Sockets a été atteinte.
WSAEFAULT
Le paramètre lpWSPData ou lpProcTable n’est pas valide.

Remarques

Les fournisseurs de services de transport Windows Sockets 2 sont des DLL avec un seul point d’entrée de procédure exportée, WSPStartup, utilisé pour la fonction d’initialisation du fournisseur de services. Toutes les autres fonctions de fournisseur de services sont rendues accessibles à la DLL Winsock 2 via la table de répartition du fournisseur de services passée dans le paramètre lpProcTable à la fonction WSPStartup . Les DLL du fournisseur de services sont chargées en mémoire par la DLL WinSock 2 uniquement lorsque cela est nécessaire, et sont déchargées lorsque leurs services ne sont plus nécessaires.

L’interface du fournisseur de services définit également plusieurs circonstances dans lesquelles un fournisseur de services de transport appelle la DLL Winsock 2 (upcalls) pour obtenir des services de support DLL. Le fournisseur de services de transport renvoie la table de distribution d’appel d’appel pour la DLL Winsock 2 dans le paramètre UpcallTable passé à la fonction WSPStartup .

La fonction WSPStartup doit être la première fonction SPI Windows Sockets appelée par un client SPI Windows Sockets sur une base par processus. Il permet au client de spécifier la version de Windows Sockets SPI requise et de fournir sa table de répartition des appels d’appel. Toutes les appels upcalls (c’est-à-dire les fonctions précédées de WPU) effectuées par le fournisseur de services Windows Sockets sont appelées par le biais de la table upcall dispatch du client. Cette fonction permet également au client de récupérer les détails de l’implémentation spécifique du fournisseur de services Windows Sockets. Le client SPI Windows Sockets ne peut émettre d’autres fonctions SPI windows Sockets qu’après un appel WSPStartup réussi. Une table de pointeurs vers le reste des fonctions SPI est récupérée via le paramètre lpProcTable qui retourne une structure WSPProc_Table .

La DLL Winsock 2 charge la DLL d’interface du fournisseur de services dans le système à l’aide des mécanismes de chargement de la bibliothèque dynamique Windows standard et l’initialise en appelant la fonction WSPStartup . Cela est généralement déclenché par une application appelant le socket ou la fonction WSASocket afin de créer un nouveau socket qui doit être associé à un fournisseur de services dont la DLL d’interface n’est pas actuellement chargée en mémoire.

Afin de prendre en charge les versions futures du SPI windows Sockets et du Ws2_32.dll, qui peuvent présenter des différences fonctionnelles par rapport au SPI Windows Sockets actuel, une négociation a lieu dans WSPStartup. L’appelant de WSPStartup (le Ws2_32.dll ou un protocole en couches) et le fournisseur de services Windows Sockets s’indiquent mutuellement la version la plus élevée de Windows Sockets qu’ils peuvent prendre en charge, et chacun confirme que la version la plus élevée de l’autre est acceptable. Lors de l’entrée dans WSPStartup, le fournisseur de services Windows Sockets examine la version demandée par le client. Si cette version est égale ou supérieure à la version la plus basse prise en charge par le fournisseur de services, l’appel réussit et le fournisseur de services retourne dans le membre wHighVersion de la structure WSPDATA la version la plus élevée qu’il prend en charge et, dans le membre wVersion , le minimum de sa version élevée et de sa version spécifiées dans le paramètre wVersionRequested . Le fournisseur de services Windows Sockets suppose ensuite que le client SPI Windows Sockets utilisera la version de Windows Sockets spécifiée dans le membre wVersion . Si le membre wVersion de la structure WSPDATA est inacceptable pour l’appelant, il doit appeler LPWSPCleanup et rechercher un autre fournisseur de services Windows Sockets ou ne pas s’initialiser.

Cette négociation permet à un fournisseur de services Windows Sockets et à un client SPI Windows Sockets de prendre en charge une gamme de versions de Windows Sockets. Un client peut utiliser correctement un fournisseur de services Windows Sockets en cas de chevauchement dans les plages de versions.

La version actuelle de la spécification Windows Sockets est la version 2.2. La DLL Winsock actuelle, Ws2_32.dll, prend en charge les applications qui demandent l’une des versions suivantes de la spécification Windows Sockets :

  • 1.0
  • 1.1
  • 2.0
  • 2.1
  • 2.2

Pour obtenir un accès complet à la nouvelle syntaxe d’une version supérieure de la spécification Windows Sockets, l’application doit négocier cette version supérieure. Dans ce cas, le paramètre wVersionRequested doit être défini pour demander la version 2.2. L’application doit également être entièrement conforme à cette version supérieure de la spécification windows Socket, comme la compilation sur le fichier d’en-tête approprié, la liaison avec une nouvelle bibliothèque ou d’autres cas spéciaux. Le fichier d’en-tête Winsock2.h pour la prise en charge de Winsock 2 est inclus dans microsoft Kit de développement logiciel Windows (Kit SDK Windows) (SDK).

Windows Sockets version 2.2 est pris en charge sur Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, Windows 2000, Windows NT 4.0 avec Service Pack 4 (SP4) et versions ultérieures, Windows Me, Windows 98 et Windows 95 OSR2. Windows Sockets version 2.2 est également pris en charge sur
Windows 95 avec Windows Socket 2 Update. Les applications sur ces plateformes doivent normalement demander Winsock 2.2 en définissant le paramètre wVersionRequested en conséquence.

Sur Windows 95 et les versions de Windows NT 3.51 et versions antérieures, Windows Sockets version 1.1 est la version la plus élevée de la spécification Windows Sockets prise en charge.

Il est légal et possible qu’une application ou une DLL écrite utilise une version inférieure de la spécification Windows Sockets prise en charge par la DLL Winsock pour négocier correctement cette version inférieure à l’aide de la fonction WSPStartup . Par exemple, une application peut demander la version 1.1 dans le paramètre wVersionRequested passé à la fonction WSPStartup sur une plateforme avec la DLL Winsock 2.2. Dans ce cas, l’application doit s’appuyer uniquement sur les fonctionnalités qui correspondent à la version demandée. Les nouveaux codes Ioctl, le nouveau comportement des fonctions existantes et les nouvelles fonctions ne doivent pas être utilisés. La négociation de version fournie par WSPStartup a été principalement utilisée pour permettre aux applications Winsock 1.1 plus anciennes développées pour Windows 95 et Windows NT 3.51 et versions antérieures de s’exécuter avec le même comportement sur les versions ultérieures de Windows. Le fichier d’en-tête Winsock.h pour la prise en charge de Winsock 1.1 est inclus dans le SDK Windows.

Le graphique suivant donne des exemples de fonctionnement de WSPStartup conjointement avec différentes versions de WS2_32.DLL et de fournisseur de services Windows Sockets.

DLL
 
versions
SP
 
versions
wVersionRequested wVersion wHighVersion Résultat final
1.1 1.1 1.1 1.1 1.1 utiliser 1.1
1.0 1.1 1.0 1.1 1.0 1.0 utiliser 1.0
1.0 1.0 1.1 1.0 1.0 1.1 utiliser 1.0
1,1 1.0 1.1 1.1 1.1 1,1 utiliser 1.1
1.1 1.0 1.1 1.0 1.0 Échec de la DLL
1.0 1.1 1.0 --- --- WSAVERNOTSUPPORTED
1.0 1.1 1.0 1.1 1.1 1.1 1.1 utiliser 1.1
1.0 1.1 2.0 1.1 2.0 1.1 1.1 utiliser 1.1
1.0 1.1 2.0 2.0 2.0 2.0 2.0 utiliser 2.0
1.0 1.1 2.0 2.1 2.2 2.2 2.2 2.2 2.2 utiliser 2.2
 

Le fragment de code suivant montre comment un client SPI Windows Sockets, qui prend en charge uniquement la version 2 de Windows Sockets SPI, effectue un appel WSPStartup :

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 usable */
    /* 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 usable */
    /* Windows Sockets service provider.                     */
    LPWSPCleanup( );
    return;   
}
 
/* The Windows Sockets service provider is acceptable. Proceed. */

Et ce fragment de code montre comment un fournisseur de services Windows Sockets qui prend en charge uniquement la version 2.2 effectue la négociation WSPStartup :

/* 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 );


Une fois que le client SPI Windows Sockets a effectué un appel WSPStartup réussi, il peut effectuer d’autres appels SPI de sockets Windows en fonction des besoins. Une fois qu’il a terminé d’utiliser les services du fournisseur de services Windows Sockets, le client doit appeler LPWSPCleanup afin de permettre au fournisseur de services Windows Sockets de libérer toutes les ressources allouées pour le client.

La fonction WSPStartup doit être appelée au moins une fois par chaque processus client et peut être appelée plusieurs fois par la DLL Winsock 2 ou d’autres entités. Une fonction LPWSPCleanup correspondante doit être appelée pour chaque appel WSPStartup réussi. Le fournisseur de services doit conserver un nombre de références par processus. Sur chaque appel WSPStartup , l’appelant peut spécifier n’importe quel numéro de version pris en charge par la DLL du fournisseur de services.

Un fournisseur de services doit stocker le pointeur vers la table de répartition de l’appel upcall du client qui est reçu en tant que paramètre UpcallTable par la fonction WSPStartup par processus. Si un processus donné appelle WSPStartup plusieurs fois, le fournisseur de services doit utiliser uniquement le pointeur de table de répartition d’appel upcall le plus récemment fourni.

Un client SPI Windows Sockets peut appeler WSPStartup plusieurs fois s’il a besoin d’obtenir les informations de structure WSPDATA plusieurs fois. À chaque appel de ce type, le client peut spécifier n’importe quel numéro de version pris en charge par le fournisseur.

Il doit y avoir un appel LPWSPCleanup correspondant à chaque appel WSPStartup réussi pour permettre aux DLL tierces d’utiliser un fournisseur de sockets Windows. Cela signifie, par exemple, que si WSPStartup est appelé trois fois, l’appel correspondant à LPWSPCleanup doit se produire trois fois. Les deux premiers appels à LPWSPCleanup ne font rien d’autre que décrémenter un compteur interne ; l’appel final LPWSPCleanup effectue toutes les allocations de ressources nécessaires.

Cette fonction (et la plupart des autres fonctions du fournisseur de services) peut être appelée dans un thread qui a commencé comme un processus 16 bits si le client est un client Windows Sockets 1.1 1 16 bits. Une limitation importante des processus 16 bits est qu’un processus 16 bits ne peut pas créer de threads. Cela est important pour les implémenteurs du fournisseur de services qui prévoient d’utiliser un thread de service interne dans le cadre de l’implémentation.

Heureusement, il n’y a généralement que deux zones où les conditions d’un thread de service sont fortes :

  • Dans l’implémentation de l’achèvement des E/S qui se chevauchent.
  • Dans l’implémentation de LPWSPEventSelect.

Ces deux zones sont uniquement accessibles par le biais de nouvelles fonctions Windows Sockets 2, qui ne peuvent être appelées que par des processus 32 bits.

Un thread de service peut être utilisé en toute sécurité si ces deux règles de conception sont soigneusement suivies :

  • Utilisez un thread de service uniquement pour les fonctionnalités qui ne sont pas disponibles pour les clients Windows Sockets 1.1 1 16 bits.
  • Créez le thread de service uniquement à la demande.

Plusieurs autres précautions s’appliquent à l’utilisation de threads de service internes. Tout d’abord, les threads entraînent généralement une pénalité de performances. Utilisez le moins possible et évitez les transitions de thread autant que possible. Deuxièmement, votre code doit toujours case activée en cas d’erreurs lors de la création de threads et échouer de manière appropriée et informative (par exemple, avec WSAEOPNOTSUPP) au cas où un événement d’exécution que vous ne vous attendiez pas aboutit à un processus 16 bits exécutant un chemin de code qui a besoin de threads.

Un fournisseur de services en couche fournit une implémentation de cette fonction, mais il est également un client de cette fonction lorsqu’il appelle WSPStartup pour initialiser la couche suivante dans la chaîne de protocole. L’appel au WSPStartup de la couche suivante peut se produire pendant l’exécution du WSPStartup de cette couche ou il peut être retardé et appelé à la demande, par exemple quand LPWSPSocket est appelé. Dans tous les cas, certaines considérations spéciales s’appliquent au paramètre lpProtocolInfo de cette fonction, car il est propagé dans les couches de la chaîne de protocole.

Le fournisseur en couches recherche la Chaîne de protocole de la structure référencée par lpProtocolInfo pour déterminer son propre emplacement dans la chaîne (en recherchant l’ID d’entrée de catalogue de la couche) et l’identité de l’élément suivant dans la chaîne. Si l’élément suivant est une autre couche, alors, lorsque le WSPStartup de la couche suivante est appelé, cette couche doit passer à la couche suivante un lpProtocolInfo qui fait référence à la même structure de WSAProtocol_Info non modifiée avec les mêmes informations de chaîne non modifiées. Toutefois, si la couche suivante est le protocole de base (c’est-à-dire le dernier élément de la chaîne), cette couche effectue une substitution lors de l’appel du WSPStartup du fournisseur de base. Dans ce cas, la structure WSAPROTOCOL_INFO du fournisseur de base doit être référencée par le paramètre lpProtocolInfo .

L’un des avantages essentiels de cette stratégie est que les fournisseurs de services de base n’ont pas besoin de connaître les chaînes de protocoles.

Cette même stratégie de propagation s’applique lors de la propagation d’une structure WSAPROTOCOL_INFO via une séquence en couches d’autres fonctions telles que LPWSPAddressToString, LPWSPDuplicateSocket, LPWSPSPSocket ou LPWSPStringToAddress.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows 2000 Professionnel [applications de bureau uniquement]
Serveur minimal pris en charge Windows 2000 Server [applications de bureau uniquement]
Plateforme cible Windows
En-tête ws2spi.h

Voir aussi

WSAProtocol_Info

LPWSPAddressToString

LPWSPStringToAddress

LPWSPCleanup

LPWSPDuplicateSocket

LPWSPEventSelect

WSPProc_Table

LPWSPSend

LPWSPSendTo

LPWSPSocket

WSPUpCallTable