Код элемента управления SIO_ASSOCIATE_PORT_RESERVATION
Описание
Код элемента управления SIO_ASSOCIATE_PORT_RESERVATION связывает сокет с постоянным резервированием или резервированием среды выполнения для блока TCP или UDP, определяемого маркером резервирования портов. Этот IOCTL должен быть выдан до привязки сокета. Если и когда сокет привязан, назначенный ему порт будет выбран из резервирования портов, определенного заданным токеном. Если из указанного резервирования нет доступных портов, вызов функции привязки завершится ошибкой.
Для выполнения этой операции вызовите функцию WSAIoctl или WSPIoctl со следующими параметрами.
int WSAIoctl(
(socket) s, // descriptor identifying a socket
SIO_ASSOCIATE_PORT_RESERVATION, // dwIoControlCode
(LPVOID) lpvInBuffer, // pointer to an INET_PORT_RESERVATION_TOKEN
(DWORD) cbInBuffer, // size, in bytes, of the input buffer
NULL, // lpvOutBuffer is a pointer to the output buffer
0, // cbOutBuffer is the size, in bytes, of the output buffer
(LPDWORD) lpcbBytesReturned, // number of bytes returned
(LPWSAOVERLAPPED) lpOverlapped, // OVERLAPPED structure
(LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine, // completion routine
);
int WSPIoctl(
(socket) s, // descriptor identifying a socket
SIO_ASSOCIATE_PORT_RESERVATION, // dwIoControlCode
(LPVOID) lpvInBuffer, // pointer to an INET_PORT_RESERVATION_TOKEN
(DWORD) cbInBuffer, // size, in bytes, of the input buffer
NULL, // lpvOutBuffer is a pointer to the output buffer
0, // cbOutBuffer is the size, in bytes, of the output buffer
(LPDWORD) lpcbBytesReturned, // number of bytes returned
(LPWSAOVERLAPPED) lpOverlapped, // OVERLAPPED structure
(LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine, // completion routine
(LPWSATHREADID) lpThreadId, // a WSATHREADID structure
(LPINT) lpErrno // a pointer to the error code.
);
Параметры
s
Дескриптор, определяющий сокет.
dwIoControlCode
Код элемента управления для операции. Используйте SIO_ASSOCIATE_PORT_RESERVATION для этой операции.
lpvInBuffer
Указатель на входной буфер. Этот параметр содержит указатель на структуру INET_PORT_RESERVATION_TOKEN с маркером для резервирования портов TCP или UDP, которые необходимо связать с сокетом.
cbInBuffer
Размер входного буфера в байтах. Этот параметр должен быть не ниже размера структуры INET_PORT_RESERVATION_TOKEN .
lpvOutBuffer
Указатель на выходной буфер. Этот параметр не используется для данной операции.
cbOutBuffer
Размер выходного буфера в байтах. Для этого параметра необходимо задать нулевое значение.
lpcbBytesReturned
Указатель на переменную, которая получает размер в байтах данных, хранящихся в выходном буфере.
Если выходной буфер слишком мал, вызов завершается ошибкой, WSAGetLastError возвращает WSAEINVAL, а параметр lpcbBytesReturned указывает на значение DWORD , равное нулю.
Если lpOverlapped имеет значение NULL, значение DWORD , на которое указывает параметр lpcbBytesReturned , возвращаемое при успешном вызове, не может быть равным нулю.
Если параметр lpOverlapped не равен NULL для перекрывающихся сокетов, будут инициированы операции, которые не могут быть завершены немедленно, а завершение будет указано позже. Значение DWORD , на которое указывает возвращаемый параметр lpcbBytesReturned , может быть равным нулю, так как размер хранимых данных не может быть определен до завершения перекрывающейся операции. Окончательное состояние завершения можно получить, когда соответствующий метод завершения получает сигнал о завершении операции.
lpvOverlapped
Указатель на структуру WSAOVERLAPPED .
Если сокеты были созданы без перекрываемого атрибута, параметр lpOverlapped игнорируется.
Если объект был открыт с перекрывающимся атрибутом, а параметр lpOverlapped не равен NULL, операция выполняется как перекрываемая (асинхронная) операция. В этом случае параметр lpOverlapped должен указывать на допустимую структуру WSAOVERLAPPED .
Для перекрывающихся операций функция WSAIoctl или WSPIoctl возвращается немедленно, а соответствующий метод завершения получает сигнал о завершении операции. В противном случае функция не возвращается, пока операция не будет завершена или не возникнет ошибка.
lpCompletionRoutine
Тип: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
Указатель на подпрограмму завершения, вызываемую при завершении операции (игнорируется для неперекрывающихся сокетов).
lpThreadId
Указатель на структуру WSATHREADID , которая будет использоваться поставщиком в последующем вызове WPUQueueApc. Поставщик должен хранить указанную структуру WSATHREADID (не указатель на нее), пока не будет возвращена функция WPUQueueApc .
Примечание Этот параметр применяется только к функции WSPIoctl .
lpErrno
Указатель на код ошибки.
Примечание Этот параметр применяется только к функции WSPIoctl .
Возвращаемое значение
Если операция завершается успешно, функция WSAIoctl или WSPIoctl возвращает ноль.
Если операция завершается сбоем или находится в состоянии ожидания, функция WSAIoctl или WSPIoctl возвращает SOCKET_ERROR. Чтобы получить расширенные сведения об ошибке, вызовите WSAGetLastError.
Код ошибки | Значение |
---|---|
WSA_IO_PENDING | Выполняется перекрываемая операция ввода-вывода. Это значение возвращается, если перекрываемая операция была успешно инициирована, а завершение будет указано позже. |
WSA_OPERATION_ABORTED | Операция ввода-вывода прекращена из-за выхода из потока или запроса приложения. Эта ошибка возвращается, если перекрываемая операция была отменена из-за закрытия сокета или выполнения команды IOCTL SIO_FLUSH . |
WSAEACCES | Предпринята попытка доступа к сокету способом, запрещенным его разрешениями на доступ. Эта ошибка возвращается при нескольких условиях для постоянных резервирований портов, которые включают следующее: у пользователя отсутствуют необходимые права администратора на локальном компьютере или приложение не запущено в расширенной оболочке в качестве встроенного администратора (RunAs administrator ). |
WSAEFAULT | Система обнаружила недопустимый адрес указателя при попытке использовать аргумент указателя в вызове. Эта ошибка возвращается из параметра lpvInBuffer, lpvoutBuffer, lpcbBytesReturned, lpOverlapped или lpCompletionRoutine не полностью содержится в допустимой части адресного пространства пользователя. |
WSAEINPROGRESS | В данный момент выполняется блокирующая операция. Эта ошибка возвращается, если функция вызывается при выполнении обратного вызова. |
WSAEINTR | Операция блокировки была прервана вызовом WSACancelBlockingCall. Эта ошибка возвращается, если операция блокировки была прервана. |
WSAEINVAL | Указан недопустимый аргумент. Эта ошибка возвращается, если параметр dwIoControlCode не является допустимой командой, или указанный входной параметр недопустим или команда не применима к указанному типу сокета. |
WSAENETDOWN | Операция на сокете обнаружила отключение сети. Эта ошибка возвращается, если произошел сбой сетевой подсистемы. |
WSAENOTSOCK | Предпринята попытка выполнения операции с тем, что не является сокетом. Эта ошибка возвращается, если дескриптор не является сокетом. |
WSAEOPNOTSUPP | Предпринятая операция не поддерживается для типа объекта, на который ссылается ссылка. Эта ошибка возвращается, если указанная команда IOCTL не поддерживается. Эта ошибка также возвращается, если поставщик транспорта не поддерживает SIO_ASSOCIATE_PORT_RESERVATION IOCTL. Эта ошибка также возвращается при попытке использовать SIO_ASSOCIATE_PORT_RESERVATION IOCTL в сокете, отличном от UDP или TCP. |
Комментарии
SIO_ASSOCIATE_PORT_RESERVATION IOCTL поддерживается в Windows Vista и более поздних версиях операционной системы.
Приложения и службы, которым необходимо зарезервировать порты, делятся на две категории. К первой категории относятся компоненты, которым требуется определенный порт в рамках операции. Такие компоненты обычно предпочитают указывать необходимый порт во время установки (например, в манифесте приложения). Вторая категория включает компоненты, которым требуется любой доступный порт или блок портов во время выполнения. Эти две категории соответствуют конкретным запросам на резервирование портов и с подстановочными знаками. Определенные запросы на резервирование могут быть постоянными или выполняться во время выполнения, а запросы на резервирование портов с подстановочными знаками поддерживаются только во время выполнения.
SIO_ASSOCIATE_PORT_RESERVATION IOCTL используется для связывания резервирования портов TCP или UDP с постоянным резервированием или резервированием во время выполнения.
Функция CreatePersistentTcpPortReservation или CreatePersistentUdpPortReservation позволяет приложению или службе зарезервировать постоянный блок портов TCP или UDP. Постоянные резервирования портов записываются в постоянное хранилище для модуля TCP или UDP в Windows. Обратите внимание, что маркер для заданного постоянного резервирования портов может изменяться при каждом перезапуске системы.
После получения постоянного резервирования портов TCP или UDP приложение может запросить назначения портов из резервирования портов, открыв сокет TCP или UDP, а затем вызвав функцию WSAIoctl , указав SIO_ASSOCIATE_PORT_RESERVATION IOCTL и передав маркер резервирования перед вызовом функции bind в сокете.
IOCTL SIO_ACQUIRE_PORT_RESERVATION можно использовать для запроса резервирования среды выполнения для блока портов TCP или UDP. Для резервирования портов среды выполнения пул портов требует, чтобы резервирования были использованы из процесса, в сокете которого было предоставлено резервирование. Резервирование портов среды выполнения длится только до времени существования сокета, в котором был вызван SIO_ACQUIRE_PORT_RESERVATION IOCTL. Напротив, постоянные резервирования портов, созданные с помощью функции CreatePersistentTcpPortReservation или CreatePersistentUdpPortReservation , могут использоваться любым процессом с возможностью получения постоянных резервирований.
После получения резервирования портов TCP или UDP среды выполнения приложение может запросить назначения портов из резервирования портов, открыв сокет TCP или UDP, а затем вызвав функцию WSAIoctl , указав SIO_ASSOCIATE_PORT_RESERVATION IOCTL и передав маркер резервирования перед вызовом функции bind в сокете.
Если параметры lpOverlapped и lpCompletionRoutine имеют значение NULL, сокет в этой функции будет рассматриваться как неперекрытый сокет. Для неперекрывающихся сокетов параметры lpOverlapped и lpCompletionRoutine игнорируются, за исключением того, что функция может блокировать, если сокеты находятся в режиме блокировки. Если сокеты находится в неблокирующем режиме, эта функция будет по-прежнему блокироваться, так как этот конкретный IOCTL не поддерживает неблокирующий режим.
Для перекрывающихся сокетов будут инициированы операции, которые не могут быть завершены немедленно, а завершение будет указано позже.
Любой IOCTL может блокироваться на неопределенный срок в зависимости от реализации поставщика услуг. Если приложение не допускает блокировки в вызове функции WSAIoctl или WSPIoctl , для ioCTL, которые особенно вероятно, будут блокироваться перекрывающиеся операции ввода-вывода.
SIO_ASSOCIATE_PORT_RESERVATION IOCTL может завершиться сбоем в WSAEINTR или WSA_OPERATION_ABORTED в следующих случаях:
- Запрос отменяется диспетчером ввода-вывода.
- Сокет закрыт.
SIO_ASSOCIATE_PORT_RESERVATION IOCTL, передаваемый функции WSAIoctl или WSPIoctl для постоянного резервирования портов, можно использовать в приложении только в том случае, если пользователь вошел в систему как член группы администраторов.
Если SIO_ASSOCIATE_PORT_RESERVATION IOCTL используется в приложении, когда пользователь не является членом группы администраторов, вызов функции завершится ошибкой и возвращается WSAEACCES .
Использование SIO_ASSOCIATE_PORT_RESERVATION IOCTL также может завершиться сбоем из-за контроля учетных записей (UAC) в Windows Vista и более поздних версиях.
Если приложение, использующее этот IOCTL с постоянным резервированием портов, выполняется пользователем, вошедшего в систему как участник группы администраторов, отличный от встроенного администратора, этот вызов завершится ошибкой, если приложение не было отмечено в файле манифеста параметром requestedExecutionLevel , для которого задано значение requireAdministrator.
Если в приложении отсутствует этот файл манифеста, пользователь, вошедший в систему как член группы администраторов, отличный от встроенного администратора, должен затем выполнять приложение в расширенной оболочке в качестве встроенного администратора (RunAs administrator
) для успешного выполнения этой функции.
См. также раздел
CreatePersistentTcpPortReservation
CreatePersistentUdpPortReservation
DeletePersistentTcpPortReservation
DeletePersistentUdpPortReservation
LookupPersistentTcpPortReservation