Função WSPStartup (ws2spi.h)
A função WSPStartup inicia o uso de uma SPI (interface do provedor de serviços) do Windows Sockets por um cliente.
Sintaxe
int WSPStartup(
[in] WORD wVersionRequested,
[out] LPWSPDATA lpWSPData,
[in] LPWSAPROTOCOL_INFOW lpProtocolInfo,
[in] WSPUPCALLTABLE UpcallTable,
[out] LPWSPPROC_TABLE lpProcTable
);
Parâmetros
[in] wVersionRequested
A versão mais alta do SPI do Windows Sockets dá suporte ao chamador que o chamador pode usar. O byte de alta ordem especifica o número da versão secundária (revisão) ; o byte de baixa ordem especifica o número de versão principal.
[out] lpWSPData
Um ponteiro para uma estrutura de dados WSPDATA que recebe informações sobre o provedor de serviços do Windows Sockets.
[in] lpProtocolInfo
Um ponteiro para uma estrutura WSAProtocol_Info que define as características do protocolo desejado. Isso é especialmente útil quando uma única DLL de provedor é capaz de instanciar vários provedores de serviços diferentes.
[in] UpcallTable
A tabela de expedição de upcall da DLL winsock 2 (Ws2_32.dll) passada em uma estrutura WSPUpCallTable .
[out] lpProcTable
Um ponteiro para a tabela de ponteiros de função SPI. Essa tabela é retornada como uma estrutura WSPProc_Table .
Retornar valor
A função WSPStartup retornará zero se for bem-sucedida. Caso contrário, ele retornará um dos códigos de erro listados abaixo.
Código do erro | Significado |
---|---|
O subsistema de rede não está disponível. Esse erro será retornado se a implementação do Windows Sockets não puder funcionar no momento porque o sistema subjacente que ele usa para fornecer serviços de rede está indisponível no momento. | |
A versão Winsock.dll está fora do intervalo. Esse erro será retornado se a versão do suporte ao SPI do Windows Sockets solicitada não for fornecida por esse provedor de serviços do Windows Sockets específico. | |
Uma operação de bloqueio do Windows Sockets 1.1 está em andamento. | |
Um limite no número de tarefas compatíveis com a implementação do Windows Sockets foi atingido. | |
O parâmetro lpWSPData ou lpProcTable é inválido. |
Comentários
Os provedores de serviços de transporte do Windows Sockets 2 são DLLs com um único ponto de entrada de procedimento exportado, WSPStartup, usado para a função de inicialização do provedor de serviços. Todas as outras funções do provedor de serviços são disponibilizadas para a DLL winsock 2 por meio da tabela de expedição do provedor de serviços passada no parâmetro lpProcTable para a função WSPStartup . As DLL do provedor de serviços são carregadas na memória pela DLL do WinSock 2 somente quando necessário e são descarregadas quando seus serviços não são mais necessários.
A interface do provedor de serviços também define várias circunstâncias em que um provedor de serviços de transporte chama a DLL winsock 2 (upcalls) para obter serviços de suporte de DLL. O provedor de serviços de transporte retorna a tabela de expedição upcall para a DLL Winsock 2 no parâmetro UpcallTable passado para a função WSPStartup .
A função WSPStartup deve ser a primeira função SPI do Windows Sockets chamada por um cliente SPI do Windows Sockets por processo. Ele permite que o cliente especifique a versão do SPI do Windows Sockets necessária e forneça sua tabela de expedição upcall. Todas as upcalls (ou seja, funções prefixadas com WPU) feitas pelo provedor de serviços do Windows Sockets são invocadas por meio da tabela de expedição upcall do cliente. Essa função também permite que o cliente recupere detalhes da implementação específica do provedor de serviços do Windows Sockets. O cliente SPI do Windows Sockets só pode emitir mais funções SPI do Windows Sockets após uma invocação WSPStartup bem-sucedida. Uma tabela de ponteiros para o restante das funções SPI é recuperada por meio do parâmetro lpProcTable que retorna uma estrutura WSPProc_Table .
A DLL do Winsock 2 carrega a DLL da interface do provedor de serviços no sistema usando os mecanismos de carregamento de biblioteca dinâmica padrão do Windows e a inicializa chamando a função WSPStartup . Isso geralmente é disparado por um aplicativo que chama o soquete ou a função WSASocket para criar um soquete que deve ser associado a um provedor de serviços cuja DLL de interface não está carregada na memória no momento.
Para dar suporte a versões futuras do SPI do Windows Sockets e do Ws2_32.dll, que podem ter diferenças funcionais em relação ao SPI atual do Windows Sockets, uma negociação ocorre no WSPStartup. O chamador do WSPStartup (o Ws2_32.dll ou um protocolo em camadas) e o provedor de serviços do Windows Sockets indicam uns aos outros a versão mais alta do Windows Sockets que eles podem dar suporte e cada um confirma que a versão mais alta do outro é aceitável. Após a entrada no WSPStartup, o provedor de serviços do Windows Sockets examina a versão solicitada pelo cliente. Se essa versão for igual ou superior à versão mais baixa com suporte pelo provedor de serviços, a chamada terá êxito e o provedor de serviços retornará no membro wHighVersion da estrutura WSPDATA a versão mais alta compatível e, no membro wVersion , o mínimo de sua versão e versão alta especificadas no parâmetro wVersionRequested . Em seguida, o provedor de serviços do Windows Sockets pressupõe que o cliente SPI do Windows Sockets usará a versão do Windows Sockets especificada no membro wVersion . Se o membro wVersion da estrutura WSPDATA for inaceitável para o chamador, ele deverá chamar LPWSPCleanup e procurar outro provedor de serviços do Windows Sockets ou falhar ao inicializar.
Essa negociação permite que um provedor de serviços do Windows Sockets e um cliente SPI do Windows Sockets ofereçam suporte a uma variedade de versões do Windows Sockets. Um cliente poderá utilizar com êxito um provedor de serviços do Windows Sockets se houver alguma sobreposição nos intervalos de versão.
A versão atual da especificação do Windows Sockets é a versão 2.2. A DLL do Winsock atual, Ws2_32.dll, dá suporte a aplicativos que solicitam qualquer uma das seguintes versões da especificação do Windows Sockets:
- 1.0
- 1,1
- 2,0
- 2.1
- 2.2
Para obter acesso completo à nova sintaxe de uma versão mais alta da especificação do Windows Sockets, o aplicativo deve negociar para essa versão mais alta. Nesse caso, o parâmetro wVersionRequested deve ser definido para solicitar a versão 2.2. O aplicativo também deve estar totalmente em conformidade com essa versão mais alta da especificação do Windows Socket, como compilar com o arquivo de cabeçalho apropriado, vincular a uma nova biblioteca ou outros casos especiais. O arquivo de cabeçalho Winsock2.h para suporte ao Winsock 2 está incluído no SDK (Microsoft Software Development Kit do Windows (SDK do Windows)).
O Windows Sockets versão 2.2 tem suporte no Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, Windows 2000, Windows NT 4.0 com Service Pack 4 (SP4) e posterior, Windows Me, Windows 98 e Windows 95 OSR2.
O Windows Sockets versão 2.2 também tem suporte no
Windows 95 com a Atualização do Windows Socket 2. Os aplicativos nessas plataformas normalmente devem solicitar o Winsock 2.2 definindo o parâmetro wVersionRequested adequadamente.
No Windows 95 e nas versões do Windows NT 3.51 e anteriores, o Windows Sockets versão 1.1 é a versão mais alta da especificação do Windows Sockets com suporte.
É legal e possível que um aplicativo ou DLL gravado use uma versão inferior da especificação do Windows Sockets compatível com a DLL winsock para negociar com êxito essa versão inferior usando a função WSPStartup . Por exemplo, um aplicativo pode solicitar a versão 1.1 no parâmetro wVersionRequested passado para a função WSPStartup em uma plataforma com a DLL Winsock 2.2. Nesse caso, o aplicativo só deve contar com recursos que se encaixam na versão solicitada. Novos códigos Ioctl, novo comportamento de funções existentes e novas funções não devem ser usados. A negociação de versão fornecida pelo WSPStartup foi usada principalmente para permitir que aplicativos Winsock 1.1 mais antigos desenvolvidos para Windows 95 e Windows NT 3.51 e anteriores sejam executados com o mesmo comportamento em versões posteriores do Windows. O arquivo de cabeçalho Winsock.h para suporte ao Winsock 1.1 está incluído no SDK do Windows.
O gráfico a seguir fornece exemplos de como o WSPStartup funciona em conjunto com diferentes WS2_32.DLL e versões do provedor de serviços do Windows Sockets (SP).
DLL |
SP |
wVersionRequested | Wversion | wHighVersion | Resultado final |
---|---|---|---|---|---|
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 | Falha na DLL |
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.0 1.1 2.0 | 1,1 | 2,0 | 1,1 | 1,1 | use 1.1 |
1.0 1.1 2.0 | 2,0 | 2,0 | 2,0 | 2.0 | use 2.0 |
1.0 1.1 2.0 2.1 2.2 | 2.2 | 2.2 | 2.2 | 2.2 | use 2.2 |
O fragmento de código a seguir demonstra como um cliente SPI do Windows Sockets, que dá suporte apenas à versão 2 do SPI do Windows Sockets, faz uma chamada 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. */
E esse fragmento de código demonstra como um provedor de serviços do Windows Sockets que dá suporte apenas à versão 2.2 executa a negociação 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 );
Depois que o cliente SPI do Windows Sockets tiver feito uma chamada WSPStartup bem-sucedida, ele poderá continuar a fazer outras chamadas SPI do Windows Sockets conforme necessário. Quando terminar de usar os serviços do provedor de serviços do Windows Sockets, o cliente deverá chamar LPWSPCleanup para permitir que o provedor de serviços do Windows Sockets libere todos os recursos alocados para o cliente.
A função WSPStartup deve ser chamada pelo menos uma vez por cada processo de cliente e pode ser chamada várias vezes pela DLL winsock 2 ou outras entidades. Uma função LPWSPCleanup correspondente deve ser chamada para cada chamada WSPStartup bem-sucedida. O provedor de serviços deve manter uma contagem de referência por processo. Em cada chamada WSPStartup , o chamador pode especificar qualquer número de versão compatível com a DLL do provedor de serviços.
Um provedor de serviços deve armazenar o ponteiro para a tabela de expedição de upcall do cliente recebida como o parâmetro UpcallTable pela função WSPStartup por processo. Se um determinado processo chamar WSPStartup várias vezes, o provedor de serviços deverá usar apenas o ponteiro de tabela de expedição upcall fornecido mais recentemente.
Um cliente SPI do Windows Sockets pode chamar WSPStartup mais de uma vez se precisar obter as informações da estrutura WSPDATA mais de uma vez. Em cada chamada desse tipo, o cliente pode especificar qualquer número de versão compatível com o provedor.
Deve haver uma chamada LPWSPCleanup correspondente a cada chamada WSPStartup bem-sucedida para permitir que DLLs de terceiros usem um provedor do Windows Sockets. Isso significa, por exemplo, que, se WSPStartup for chamado três vezes, a chamada correspondente para LPWSPCleanup deverá ocorrer três vezes. As duas primeiras chamadas para LPWSPCleanup não fazem nada além de diminuir um contador interno; a chamada LPWSPCleanup final faz toda a desalocação de recursos necessária.
Essa função (e a maioria das outras funções do provedor de serviços) pode ser invocada em um thread iniciado como um processo de 16 bits se o cliente for um cliente windows sockets 1.1 de 16 bits. Uma limitação importante dos processos de 16 bits é que um processo de 16 bits não pode criar threads. Isso é significativo para os implementadores do provedor de serviços que planejam usar um thread de serviço interno como parte da implementação.
Felizmente, geralmente há apenas duas áreas em que as condições para um thread de serviço são fortes:
- Na implementação da conclusão de E/S sobreposta.
- Na implementação de LPWSPEventSelect.
Essas duas áreas só podem ser acessadas por meio de novas funções do Windows Sockets 2, que só podem ser invocadas por processos de 32 bits.
Um thread de serviço poderá ser usado com segurança se essas duas regras de design forem seguidas cuidadosamente:
- Use um thread de serviço somente para funcionalidade que não esteja disponível para clientes do Windows Sockets 1.1 de 16 bits.
- Crie o thread de serviço somente sob demanda.
Várias outras advertências se aplicam ao uso de threads de serviço internos. Primeiro, os threads geralmente têm alguma penalidade de desempenho. Use o mínimo possível e evite transições de thread sempre que possível. Em segundo lugar, seu código deve sempre marcar para erros na criação de threads e falhar normalmente e de forma informativa (por exemplo, com WSAEOPNOTSUPP) caso algum evento de execução você não espera resultados em um processo de 16 bits executando um caminho de código que precisa de threads.
Um provedor de serviços em camadas fornece uma implementação dessa função, mas também é um cliente dessa função quando chama WSPStartup para inicializar a próxima camada na cadeia de protocolos. A chamada para o WSPStartup da próxima camada pode ocorrer durante a execução do WSPStartup dessa camada ou pode ser atrasada e chamada sob demanda, como quando LPWSPSocket é chamado. De qualquer forma, algumas considerações especiais se aplicam ao parâmetro lpProtocolInfo dessa função, pois ela é propagada pelas camadas da cadeia de protocolos.
O provedor em camadas pesquisa o ProtocolChain da estrutura referenciada por lpProtocolInfo para determinar sua própria localização na cadeia (pesquisando a própria ID de entrada de catálogo da camada) e a identidade do próximo elemento na cadeia. Se o próximo elemento for outra camada, quando o WSPStartup da próxima camada for chamado, essa camada deverá passar para a próxima camada um lpProtocolInfo que referencie a mesma estrutura de WSAProtocol_Info não modificada com as mesmas informações de cadeia não modificadas. No entanto, se a próxima camada for o protocolo base (ou seja, o último elemento na cadeia), essa camada executará uma substituição ao chamar o WSPStartup do provedor base. Nesse caso, a estrutura de WSAPROTOCOL_INFO do provedor base deve ser referenciada pelo parâmetro lpProtocolInfo .
Um benefício vital dessa política é que os provedores de serviços base não precisam estar cientes das cadeias de protocolo.
Essa mesma política de propagação se aplica ao propagar uma estrutura WSAPROTOCOL_INFO por meio de uma sequência em camadas de outras funções, como LPWSPAddressToString, LPWSPDuplicateSocket, LPWSPSocket ou LPWSPStringToAddress.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Windows 2000 Professional [somente aplicativos da área de trabalho] |
Servidor mínimo com suporte | Windows 2000 Server [somente aplicativos da área de trabalho] |
Plataforma de Destino | Windows |
Cabeçalho | ws2spi.h |