SIO_RELEASE_PORT_RESERVATION コントロール コード

説明

SIO_RELEASE_PORT_RESERVATION制御コードは、TCP または UDP ポートのブロックのランタイム予約を解放します。 解放するランタイム予約は、 SIO_ACQUIRE_PORT_RESERVATION IOCTL を使用して発行プロセスから取得されている必要があります。

この操作を実行するには、次のパラメーターを指定して WSAIoctl または WSPIoctl 関数を呼び出します。

int WSAIoctl(
  (socket) s,             // descriptor identifying a socket
  SIO_RELEASE_PORT_RESERVATION, // dwIoControlCode
  (LPVOID) lpvInBuffer,  // pointer to a INET_PORT_RESERVATION_TOKEN structure
  (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_RELEASE_PORT_RESERVATION, // dwIoControlCode
  (LPVOID) lpvInBuffer,  // pointer to a INET_PORT_RESERVATION_TOKEN structure
  (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_RELEASE_PORT_RESERVATION を使用します。

lpvInBuffer

入力バッファーへのポインター。 このパラメーターには、TCP または UDP ポート予約を解放するためのトークンを含む INET_PORT_RESERVATION_TOKEN 構造体へのポインターが含まれています。

cbInBuffer

入力バッファーのサイズ (バイト単位)。 このパラメーターは、少なくとも INET_PORT_RESERVATION_TOKEN 構造体のサイズである必要があります。

lpvOutBuffer

出力バッファーへのポインター。 このパラメーターは、この操作では使用されません。

cbOutBuffer

出力バッファーのサイズ (バイト単位)。 このパラメーターは 0 に設定する必要があります。

lpcbBytesReturned

出力バッファーに格納されているデータのサイズ (バイト単位) を受け取る変数へのポインター。

出力バッファーが小さすぎる場合、呼び出しは失敗し、 WSAGetLastError はWSAEINVAL を返し、 lpcbBytesReturned パラメーターはDWORD 値 0 を指します。

lpOverlappedNULL の場合、正常な呼び出しで返される lpcbBytesReturned パラメーターが指す DWORD 値を 0 にすることはできません。

重複するソケットに 対して lpOverlapped パラメーターが NULL でない場合、すぐには完了できない操作が開始され、完了は後で示されます。 返される lpcbBytesReturned パラメーターが指す DWORD 値は、重複する操作が完了するまで格納されているデータのサイズを決定できないため、0 になる可能性があります。 最終的な完了状態は、操作が完了したときに適切な完了メソッドが通知されたときに取得できます。

lpvOverlapped

WSAOVERLAPPED 構造体へのポインター。

重複する属性なしでソケット s が作成された場合、 lpOverlapped パラメーターは無視されます。

重複した属性を使用して s を開き、 lpOverlapped パラメーターが NULL でない場合、操作は重複 (非同期) 操作として実行されます。 この場合、 lpOverlapped パラメーターは有効な WSAOVERLAPPED 構造体を指している必要があります。

重複する操作の場合、 WSAIoctl または WSPIoctl 関数は直ちに戻り、操作が完了すると適切な完了メソッドが通知されます。 それ以外の場合、関数は操作が完了するかエラーが発生するまで戻りません。

lpCompletionRoutine

種類: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

操作が完了したときに呼び出される完了ルーチンへのポインター (重複していないソケットの場合は無視されます)。

lpThreadId

WPUQueueApc への後続の呼び出しでプロバイダーによって使用される WSATHREADID 構造体へのポインター。 プロバイダーは、WPUQueueApc 関数が戻るまで、参照先の WSATHREADID 構造体 (同じへのポインターではありません) を格納する必要があります。

メモ このパラメーターは 、WSPIoctl 関数にのみ適用されます。

lpErrno

エラー コードへのポインター。

メモ このパラメーターは 、WSPIoctl 関数にのみ適用されます。

戻り値

操作が正常に完了すると、 WSAIoctl または WSPIoctl 関数は 0 を返します。

操作が失敗した場合、または保留中の場合、 WSAIoctl または WSPIoctl 関数は SOCKET_ERRORを返します。 拡張エラー情報を取得するには、 WSAGetLastError を呼び出します。

エラー コード 意味
WSA_IO_PENDING 重複した I/O 操作が進行中です。 この値は、重複した操作が正常に開始され、完了が後で示される場合に返されます。
WSA_OPERATION_ABORTED スレッドの終了またはアプリケーションの要求が原因で、I/O 操作が中止されました。 このエラーは、ソケットのクローズまたは SIO_FLUSH IOCTL コマンドの実行により、重複した操作が取り消された場合 返されます。
WSAEFAULT 呼び出しでポインター引数を使用しようとしたときに、システムによって無効なポインター アドレスが検出されました。 このエラーは、 lpOverlapped パラメーターまたは lpCompletionRoutine パラメーターが、ユーザー アドレス空間の有効な部分に完全に含まれていない場合に返されます。
WSAEINPROGRESS 現在、ブロック操作を実行中です。 コールバックの実行中に関数が呼び出されると、このエラーが返されます。
WSAEINTR WSACancelBlockingCall の呼び出しによってブロック操作が中断されました。 このエラーは、ブロック操作が中断された場合に返されます。
WSAEINVAL 無効な引数が指定されました。 このエラーは、 dwIoControlCode パラメーターが有効なコマンドではない場合、または指定された入力パラメーターが受け入れられない場合、または指定されたソケットの型にコマンドが適用されない場合に返されます。
WSAENETDOWN ソケット操作によりネットワークの停止が検出されました。 このエラーは、ネットワーク サブシステムが失敗した場合に返されます。
WSAENOTSOCK ソケットではない操作が試行されました。 記述子 s がソケットでない場合、このエラーが返されます。
WSAEOPNOTSUPP 試行された操作は、参照されるオブジェクトの種類ではサポートされていません。 このエラーは、指定された IOCTL コマンドがサポートされていない場合に返されます。 このエラーは、 SIO_RELEASE_PORT_RESERVATION IOCTL がトランスポート プロバイダーでサポートされていない場合にも返されます。 このエラーは、UDP または TCP 以外のソケットで SIO_RELEASE_PORT_RESERVATION IOCTL を使用しようとするとも返されます。

注釈

SIO_RELEASE_PORT_RESERVATION IOCTL は、Windows Vista 以降のバージョンのオペレーティング システムでサポートされています。

ポートを予約する必要があるアプリケーションとサービスは、2 つのカテゴリに分類されます。 最初のカテゴリには、操作の一部として特定のポートを必要とするコンポーネントが含まれています。 このようなコンポーネントは、通常、インストール時に必要なポートを指定することを好みます (たとえば、アプリケーション マニフェストで)。 2 番目のカテゴリには、実行時に使用可能なポートまたはポート ブロックが必要なコンポーネントが含まれています。 これら 2 つのカテゴリは、特定のポート予約要求とワイルドカード ポート予約要求に対応しています。 特定の予約要求は永続的または実行時である場合があります。一方、ワイルドカード ポート予約要求は実行時にのみサポートされます。

SIO_ACQUIRE_PORT_RESERVATION IOCTL は、TCP ポートまたは UDP ポートのブロックのランタイム予約を要求するために使用されます。 ランタイム ポート予約の場合、ポート プールでは、予約が許可されたソケット上のプロセスから予約を使用する必要があります。 ランタイム ポート予約は、 SIO_ACQUIRE_PORT_RESERVATION IOCTL が呼び出されたソケットの有効期間の間だけ続きます。 これに対し、 CreatePersistentTcpPortReservation または CreatePersistentUdpPortReservation 関数を使用して作成された永続的なポート予約は、永続的な予約を取得できる任意のプロセスで使用できます。

SIO_RELEASE_PORT_RESERVATION IOCTL は、TCP または UDP ポートのブロックのランタイム予約を解放するために使用されます。

lpOverlapped パラメーターと lpCompletionRoutine パラメーターの両方が NULL の場合、この関数のソケットは重複しないソケットとして扱われます。 重複していないソケットの場合、 lpOverlapped パラメーターと lpCompletionRoutine パラメーターは無視されます。ただし、ソケット s がブロック モードの場合、関数はブロックできます。 ソケット s が非ブロッキング モードの場合、この特定の IOCTL では非ブロッキング モードがサポートされていないため、この関数はブロックされます。

重複するソケットの場合、すぐに完了できない操作が開始され、完了は後で示されます。

サービス プロバイダーの実装によっては、IOCTL が無期限にブロックされる場合があります。 アプリケーションが WSAIoctl 関数呼び出しまたは WSPIoctl 関数呼び出しでブロックを許容できない場合は、特にブロックする可能性が高い IOCTL に対して重複した I/O が推奨されます。

SIO_RELEASE_PORT_RESERVATION IOCTL は、次の場合に WSAEINTR またはWSA_OPERATION_ABORTEDで失敗する可能性があります。

  • 要求は I/O マネージャーによって取り消されます。
  • ソケットが閉じています。

次の例では、ランタイム ポート予約を取得し、ランタイム ポート予約を解放します。

#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 <stdio.h>
#include <stdlib.h>

// 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

    INET_PORT_RANGE portRange = { 0 };
    INET_PORT_RESERVATION_INSTANCE portRes = { 0 };

    unsigned long status = 0;

    WSADATA wsaData = { 0 };
    int iResult = 0;

    SOCKET sock = INVALID_SOCKET;
    int iFamily = AF_INET;
    int iType = 0;
    int iProtocol = 0;

    SOCKET sockRes = INVALID_SOCKET;

    DWORD bytesReturned = 0;

    // Validate the parameters
    if (argc != 6) {
        wprintf
            (L"usage: %s <addressfamily> <type> <protocol> <StartingPort> <NumberOfPorts>\n",
             argv[0]);
        wprintf(L"Opens a socket for the specified family, type, & protocol\n");
        wprintf
            (L"and then acquires a runtime port reservation for the protocol specified\n");
        wprintf(L"%ws example usage\n", argv[0]);
        wprintf(L"   %ws 2 2 17 5000 20\n", argv[0]);
        wprintf(L"   where AF_INET=2 SOCK_DGRAM=2 IPPROTO_UDP=17 StartPort=5000 NumPorts=20", argv[0]);

        return 1;
    }

    iFamily = _wtoi(argv[1]);
    iType = _wtoi(argv[2]);
    iProtocol = _wtoi(argv[3]);

    startPort = _wtoi(argv[4]);
    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[5]);
    if (numPorts < 0) {
        wprintf(L"Number of ports must be a positive number\n");
        return 1;
    }

    portRange.StartPort = startPortns;
    portRange.NumberOfPorts = (USHORT) numPorts;

    // 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());
        WSACleanup();
        return 1;
    } else {
        wprintf(L"socket function succeeded\n");

        iResult =
            WSAIoctl(sock, SIO_ACQUIRE_PORT_RESERVATION, (LPVOID) & portRange,
                     sizeof (INET_PORT_RANGE), (LPVOID) & portRes,
                     sizeof (INET_PORT_RESERVATION_INSTANCE), &bytesReturned, NULL, NULL);
        if (iResult != 0) {
            wprintf(L"WSAIoctl(SIO_ACQUIRE_PORT_RESERVATION) failed with error = %d\n",
                    WSAGetLastError());
            closesocket(sock);
            WSACleanup();
            return 1;
        } else {
            wprintf
                (L"WSAIoctl(SIO_ACQUIRE_PORT_RESERVATION) succeeded, bytesReturned = %u\n",
                 bytesReturned);
            wprintf(L"  Starting port=%d,  Number of Ports=%d, Token=%I64d\n",
                    htons(portRes.Reservation.StartPort),
                    portRes.Reservation.NumberOfPorts, portRes.Token);

            iResult =
                WSAIoctl(sock, SIO_RELEASE_PORT_RESERVATION, (LPVOID) & portRes.Token,
                         sizeof (ULONG64), NULL, 0, &bytesReturned, NULL, NULL);
            if (iResult != 0) {
                wprintf
                    (L"WSAIoctl(SIO_RELEASE_PORT_RESERVATION) failed with error = %d\n",
                     WSAGetLastError());
            } else {
                wprintf
                    (L"WSAIoctl(SIO_RELEASE_PORT_RESERVATION) succeeded, bytesReturned = %u\n",
                     bytesReturned);
            }
        }

        if (sock != INVALID_SOCKET) {
            iResult = closesocket(sock);
            if (iResult == SOCKET_ERROR) {
                wprintf(L"closesocket for first socket failed with error = %d\n",
                        WSAGetLastError());
            }
        }
    }

    WSACleanup();

    return 0;
}

こちらもご覧ください

CreatePersistentTcpPortReservation

CreatePersistentUdpPortReservation

DeletePersistentTcpPortReservation

DeletePersistentUdpPortReservation

INET_PORT_RESERVATION_TOKEN

LookupPersistentTcpPortReservation

LookupPersistentUdpPortReservation

SIO_ACQUIRE_PORT_RESERVATION

SIO_ASSOCIATE_PORT_RESERVATION

socket

WSAGetLastError

WSAGetOverlappedResult

WSAIoctl

WSAOVERLAPPED

WSASocketA

WSASocketW