Função CreatePersistentTcpPortReservation (iphlpapi.h)
A função CreatePersistentTcpPortReservation cria uma reserva de porta TCP persistente para um bloco consecutivo de portas TCP no computador local.
Sintaxe
IPHLPAPI_DLL_LINKAGE ULONG CreatePersistentTcpPortReservation(
[in] USHORT StartPort,
[in] USHORT NumberOfPorts,
[out] PULONG64 Token
);
Parâmetros
[in] StartPort
O número da porta TCP inicial na ordem de bytes de rede.
[in] NumberOfPorts
O número de números de porta TCP a serem reservados.
[out] Token
Um ponteiro para um token de reserva de porta retornado se a função for bem-sucedida.
Retornar valor
Se a função for bem-sucedida, o valor retornado será NO_ERROR.
Se a função falhar, o valor retornado será um dos códigos de erro a seguir.
Código de retorno | Descrição |
---|---|
|
Acesso negado. Esse erro é retornado sob várias condições que incluem o seguinte: o usuário não tem os privilégios administrativos necessários no computador local ou o aplicativo não está em execução em um shell aprimorado como administrador interno (administrador RunAs). |
|
Um parâmetro inválido foi passado para a função.
Esse erro será retornado se zero for passado nos parâmetros StartPort ou NumberOfPorts . Esse erro também será retornado se o parâmetro NumberOfPorts for muito grande, um bloco de portas, dependendo do parâmetro StartPort , de que o bloco de portas alocável excederia a porta máxima que pode ser alocada. |
|
O processo não pode acessar o arquivo porque ele está sendo usado por outro processo. Esse erro será retornado se uma porta TCP no bloco de portas TCP especificadas pelos parâmetros StartPort e NumberOfPorts já estiver sendo usada. Esse erro também será retornado se uma reserva persistente para um bloco de portas TCP especificado pelos parâmetros StartPort e NumberOfPorts corresponder ou sobrepor uma reserva persistente para um bloco de portas TCP que já foi criado. |
|
Use FormatMessage para obter a cadeia de caracteres de mensagem para o erro retornado. |
Comentários
A função CreatePersistentTcpPortReservation é definida no Windows Vista e posterior.
A função CreatePersistentTcpPortReservation é usada para adicionar uma reserva persistente para um bloco de portas TCP.
Aplicativos e serviços que precisam reservar portas se enquadram em duas categorias. A primeira categoria inclui componentes que precisam de uma porta específica como parte de sua operação. Esses componentes geralmente preferem especificar a porta necessária no momento da instalação (em um manifesto do aplicativo, por exemplo). A segunda categoria inclui componentes que precisam de qualquer porta disponível ou bloco de portas em runtime.
Essas duas categorias correspondem a solicitações de reserva de porta curinga e específicas. Solicitações de reserva específicas podem ser persistentes ou runtime, enquanto as solicitações de reserva de porta curinga só têm suporte no runtime.
A função CreatePersistentTcpPortReservation fornece a capacidade de um aplicativo ou serviço reservar um bloco persistente de portas TCP. As reservas de porta TCP persistentes são registradas em um repositório persistente para o módulo TCP no Windows.
Um chamador obtém uma reserva de porta persistente especificando quantas portas são necessárias e se um intervalo específico é necessário. Se a solicitação puder ser atendida, a função CreatePersistentTcpPortReservation retornará um token de ULONG64 opaco exclusivo, que identifica posteriormente a reserva. Uma reserva de porta TCP persistente pode ser liberada chamando a função DeletePersistentTcpPortReservation . Observe que o token para uma determinada reserva de porta TCP persistente pode ser alterado sempre que o sistema é reiniciado.
O Windows não implementa a segurança entre componentes para reservas persistentes obtidas usando essas funções. Isso significa que, se um componente receber a capacidade de obter reservas de porta persistentes, esse componente obterá automaticamente a capacidade de consumir quaisquer reservas de porta persistentes concedidas a qualquer outro componente no sistema. A segurança em nível de processo é imposta para reservas de runtime, mas esse controle não pode ser estendido para reservas de porta persistentes criadas usando a função CreatePersistentTcpPortReservation ou CreatePersistentUdpPortReservation .
Depois que uma reserva de porta TCP persistente tiver sido obtida, um aplicativo poderá solicitar atribuições de porta da reserva de porta TCP abrindo um soquete TCP e chamando a função WSAIoctl especificando o SIO_ASSOCIATE_PORT_RESERVATION IOCTL e passando o token de reserva antes de emitir uma chamada para a função de associação no soquete.
O SIO_ACQUIRE_PORT_RESERVATION IOCTL pode ser usado para solicitar uma reserva de runtime para um bloco de portas TCP ou UDP. Para reservas de porta de runtime, o pool de portas exige que as reservas sejam consumidas do processo em cujo soquete a reserva foi concedida. As reservas de porta de runtime duram apenas o tempo de vida do soquete no qual o SIO_ACQUIRE_PORT_RESERVATION IOCTL foi chamado. Por outro lado, as reservas de porta persistentes criadas usando a função CreatePersistentTcpPortReservation podem ser consumidas por qualquer processo com a capacidade de obter reservas persistentes.
A função CreatePersistentTcpPortReservation só pode ser chamada por um usuário conectado como membro do grupo Administradores. Se CreatePersistentTcpPortReservation for chamado por um usuário que não seja membro do grupo Administradores, a chamada de função falhará e ERROR_ACCESS_DENIED será retornado. Essa função também pode falhar devido ao UAC (controle de conta de usuário) no Windows Vista e posterior. Se um aplicativo que contém essa função for executado por um usuário conectado como um membro do grupo Administradores diferente do Administrador interno, essa chamada falhará, a menos que o aplicativo tenha sido marcado no arquivo de manifesto com um requestedExecutionLevel definido como requireAdministrator. Se o aplicativo não tiver esse arquivo de manifesto, um usuário conectado como membro do grupo Administradores diferente do Administrador interno deverá executar o aplicativo em um shell aprimorado como administrador interno (administrador RunAs) para que essa função tenha êxito.
Exemplos
O exemplo a seguir cria uma reserva de porta TCP persistente, cria um soquete e aloca uma porta da reserva de porta e fecha o soquete e exclui a reserva de porta TCP.
Este exemplo deve ser executado por um usuário que seja membro do grupo Administradores. A maneira mais simples de executar este exemplo é em um shell aprimorado como administrador interno (administrador RunAs).
#ifndef UNICODE
#define UNICODE
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h.>
#include <winsock2.h>
#include <mstcpip.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with iphlpapi.lib
#pragma comment(lib, "iphlpapi.lib")
// Need to link with Ws2_32.lib for Winsock functions
#pragma comment(lib, "ws2_32.lib")
int wmain(int argc, WCHAR ** argv)
{
// Declare and initialize variables
int startPort = 0; // host byte order
int numPorts = 0;
USHORT startPortns = 0; // Network byte order
ULONG64 resToken = { 0 };
unsigned long status = 0;
WSADATA wsaData = { 0 };
int iResult = 0;
SOCKET sock = INVALID_SOCKET;
int iFamily = AF_INET;
int iType = SOCK_STREAM;
int iProtocol = IPPROTO_TCP;
DWORD bytesReturned = 0;
// Note that the sockaddr_in struct works only with AF_INET not AF_INET6
// An application needs to use the sockaddr_in6 for AF_INET6
sockaddr_in service;
sockaddr_in sockName;
int nameLen = sizeof(sockName);
// Validate the parameters
if (argc != 3) {
wprintf(L"usage: %s <Starting Port> <Number of Ports>\n",
argv[0]);
wprintf(L"Creates a persistent TCP port reservation\n");
wprintf(L"Example usage:\n");
wprintf(L" %s 5000 20\n", argv[0]);
wprintf(L" where StartPort=5000 NumPorts=20");
return 1;
}
startPort = _wtoi(argv[1]);
if (startPort < 0 || startPort > 65535) {
wprintf(L"Starting point must be either 0 or between 1 and 65,535\n");
return 1;
}
startPortns = htons((USHORT) startPort);
numPorts = _wtoi(argv[2]);
if (numPorts < 0) {
wprintf(L"Number of ports must be a positive number\n");
return 1;
}
status =
CreatePersistentTcpPortReservation((USHORT) startPortns, (USHORT) numPorts,
&resToken);
if (status != NO_ERROR) {
wprintf(L"CreatePersistentTcpPortReservation returned error: %ld\n", status);
return 1;
}
wprintf(L"CreatePersistentTcpPortReservation call succeeded\n");
wprintf(L" Token = %I64d\n", resToken);
// Comment out this block if you don't want to create a socket and associate it with the
// persistent reservation
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed with error = %d\n", iResult);
// return 1;
}
sock = socket(iFamily, iType, iProtocol);
if (sock == INVALID_SOCKET)
wprintf(L"socket function failed with error = %d\n", WSAGetLastError());
else {
wprintf(L"socket function succeeded\n");
iResult =
WSAIoctl(sock, SIO_ASSOCIATE_PORT_RESERVATION, (LPVOID) & resToken,
sizeof (ULONG64), NULL, 0, &bytesReturned, NULL, NULL);
if (iResult != 0) {
wprintf
(L"WSAIoctl(SIO_ASSOCIATE_PORT_RESERVATION) failed with error = %d\n",
WSAGetLastError());
} else {
wprintf(L"WSAIoctl(SIO_ASSOCIATE_PORT_RESERVATION) succeeded, bytesReturned = %u\n",
bytesReturned);
service.sin_family = AF_INET;
service.sin_addr.s_addr = INADDR_ANY;
service.sin_port = 0;
iResult = bind(sock, (SOCKADDR*) &service, sizeof(service) );
if (iResult == SOCKET_ERROR)
wprintf(L"bind failed with error = %d\n", WSAGetLastError());
else {
wprintf(L"bind succeeded\n");
iResult = getsockname(sock, (SOCKADDR*) &sockName, &nameLen);
if (iResult == SOCKET_ERROR)
wprintf(L"getsockname failed with error = %d\n", WSAGetLastError() );
else {
wprintf(L"getsockname succeeded\n");
wprintf(L"Port number allocated = %u\n", ntohs(sockName.sin_port) );
}
}
}
if (sock != INVALID_SOCKET) {
iResult = closesocket(sock);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error = %d\n", WSAGetLastError());
WSACleanup();
}
}
}
// comment out this block of code if you don't want to delete the reservation just created
status = DeletePersistentTcpPortReservation((USHORT) startPortns, (USHORT) numPorts);
if (status != NO_ERROR) {
wprintf(L"DeletePersistentTcpPortReservation returned error: %ld\n", status);
return 1;
}
wprintf(L"DeletePersistentTcpPortReservation call succeeded\n");
return 0;
}
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Windows Vista [somente aplicativos da área de trabalho] |
Servidor mínimo com suporte | Windows Server 2008 [somente aplicativos da área de trabalho] |
Plataforma de Destino | Windows |
Cabeçalho | iphlpapi.h |
Biblioteca | Iphlpapi.lib |
DLL | Iphlpapi.dll |
Confira também
CreatePersistentUdpPortReservation
DeletePersistentTcpPortReservation
DeletePersistentUdpPortReservation
LookupPersistentTcpPortReservation
LookupPersistentUdpPortReservation