LPNSPIOCTL
コールバックシグネチャ
INT LPNSPIOCTL(
HANDLE hLookup,
DWORD dwControlCode,
void* lpvInBuffer,
DWORD cbInBuffer,
void* lpvOutBuffer,
DWORD cbOutBuffer,
DWORD* lpcbBytesReturned,
WSACOMPLETION* lpCompletion,
WSATHREADID* lpThreadId
);パラメーター
| フィールド | 型 | 説明 | ||||
|---|---|---|---|---|---|---|
| hLookup | HANDLE | 以前の NSPLookupServiceBegin 関数の呼び出しで返されたルックアップハンドル。 | ||||
| dwControlCode | DWORD | 実行する操作の制御コード。 dwControlCode パラメーターに使用できる値は、名前空間プロバイダーによって決まります。 次の値は、Network Location Awareness (NS_NLA) 名前空間プロバイダーを含むいくつかの Microsoft 名前空間プロバイダーでサポートされています。この IOCTL は Winsock2.h ヘッダーファイルで定義されています。
| ||||
| lpvInBuffer | void* | 入力バッファーへのポインター。 | ||||
| cbInBuffer | DWORD | 入力バッファーのサイズ (バイト単位)。 | ||||
| lpvOutBuffer | void* | 出力バッファーへのポインター。 | ||||
| cbOutBuffer | DWORD | 出力バッファーのサイズ (バイト単位)。 | ||||
| lpcbBytesReturned | DWORD* | 返されたバイト数へのポインター。 | ||||
| lpCompletion | WSACOMPLETION* | 非同期処理に使用される WSACOMPLETION 構造体へのポインター。ブロッキング (同期) 実行を強制するには、lpCompletion に NULL を設定します。 | ||||
| lpThreadId | WSATHREADID* | プロバイダーが後続の WPUQueueApc の呼び出しで使用する WSATHREADID 構造体へのポインター。プロバイダーは、 WPUQueueApc 関数が戻るまで、参照先の WSATHREADID 構造体 (ポインターではなく) を保持しておく必要があります。 |
公式ドキュメント
NSPIoctl 関数は、名前空間サービスプロバイダーに IOCTL を送信します。
戻り値
エラーが発生せず、操作が即座に完了した場合、 NSPIoctl 関数は NO_ERROR (0) を返す必要があります。この場合、完了ルーチンが指定されていれば、それはすでにキューに登録されていることに注意してください。
NSPIoctl 関数は、ルーチンが失敗した場合に SOCKET_ERROR (すなわち 1) を返し、 WSASetLastError を使用して適切なエラーコードを設定する必要があります。
エラーコード WSA_IO_PENDING は、オーバーラップ操作が正常に開始され、完了が後で通知されることを示します。それ以外のエラーコードは、オーバーラップ操作が開始されておらず、完了通知も行われないことを示します。
| エラーコード | 説明 |
|---|---|
| hLookup パラメーターが、 NSPLookupServiceBegin が返した有効なクエリハンドルではありませんでした。 | |
| オーバーラップ操作が正常に開始され、完了は後で通知されます。 | |
| lpvInBuffer、cbInBuffer、lpvOutBuffer、cbOutBuffer、または lpCompletion 引数の全体が、ユーザーアドレス空間の有効な領域に収まっていません。あるいは、cbInBuffer または cbOutBuffer 引数が小さすぎるため、必要な割り当てサイズを示すように引数が変更されます。 | |
| 指定されたパラメーターが受け入れられないか、指定された操作にとって意味をなさないにもかかわらず、操作が複数の名前空間からの結果を不適切に返しています。 | |
| ネットワークサブシステムに障害が発生しました。 | |
| この操作はサポートされていません。このエラーは、名前空間プロバイダーがこの関数を実装していない場合に返されます。また、指定された dwControlCode が認識されないコマンドである場合にも返されることがあります。 | |
|
リソースが一時的に使用できません。ソケットはオーバーラップ I/O (非同期処理) を使用していないにもかかわらず、lpCompletion パラメーターが **NULL** 以外です。
このエラーは、SIO_NSP_NOTIFY_CHANGE IOCTL において lpCompletion パラメーターが NULL の場合 (ポーリング) に、クエリセットが引き続き有効であることを示す特別な通知として使用されます。 |
解説(Remarks)
NSPIoctl 関数は、クエリハンドルに関連付けられた動作パラメーターを設定または取得するために、名前空間プロバイダーへ I/O 制御コードを送信するときに使用します。hLookup パラメーターは、以前に NSPLookupServiceBegin 関数が返した名前空間プロバイダーのクエリへのハンドルです (ソケットハンドルではありません)。
名前空間プロバイダーに送信された IOCTL は、その名前空間の実装によっては無期限にブロックする可能性があります。アプリケーションが NSPIoctl 関数の呼び出しでのブロックを許容できない場合は、オーバーラップ I/O を使用し、lpCompletion パラメーターが WSACOMPLETION 構造体を指すようにする必要があります。 NSPIoctl 関数の呼び出しを非ブロッキングにして即座に戻すには、WSACOMPLETION 構造体の Type メンバーに NSP_NOTIFY_IMMEDIATELY を設定します。
lpCompletion が NULL の場合、 NSPIoctl 関数はブロッキング呼び出しとして実行されます。名前空間プロバイダーは即座に戻る必要があり、ブロックしてはなりません。ただし、この動作を守らせる責任は各名前空間プロバイダーにあります。
次の IOCTL コードは、いくつかの Microsoft 名前空間プロバイダーでサポートされています。
この IOCTL をサポートする Microsoft 名前空間プロバイダーには、次のものがあります。
- NS_NLA - Network Location Awareness (NLA) 名前空間プロバイダー。
- NS_PNRPNAME - Peer Name Resolution Protocol (PNRP) 名前空間プロバイダー。
- NS_PNRPCLOUD - Peer Name Resolution Protocol (PNRP) クラウド名前空間プロバイダー。
この IOCTL をサポートする Microsoft 以外の名前空間プロバイダーがインストールされている場合もあります。
lpCompletion パラメーターが NULL の場合、この IOCTL は特別な動作をします。この IOCTL で lpCompletion パラメーターが NULL の場合、この操作はポーリングとなり、即座に戻ります。クエリセットが引き続き有効であれば、クエリセットが有効であることの通知として WSAEWOULDBLOCK が返されます。クエリセットが変更されて無効になっている場合は、クエリセットの無効化をポーリングで検出できたことを示す NO_ERROR が返されます。
lpCompletion パラメーターが NULL ではなく、WSACOMPLETION 構造体を指している場合、オーバーラップ操作が正常に開始され、完了が後で通知されるのであれば、NSPIoctl 関数は WSA_IO_PENDING を返します。クエリセットがまだ有効かどうかをアプリケーションに通知するために、WSACOMPLETION 構造体で指定された方法が使用されます。
すべての名前解決プロトコルがこの機能をサポートできるわけではないため、この関数の呼び出しが WSAEOPNOTSUPP で失敗することがあります。複数のプロバイダーのデータを含むクエリではこの IOCTL を呼び出せず、 WSAEINVAL が返されます。
lpvInBuffer、cbInBuffer、lpvOutBuffer、cbOutBuffer の各パラメーターは、現在のところ Microsoft 名前空間プロバイダーでは無視されます。
シングルスレッドのアプリケーションでは、NSPIoctl 関数の一般的な使用方法は次のとおりです。クエリデータがまだ有効であることを確認するため、NSPLookupServiceNext 関数を呼び出すたびに、dwControlCode パラメーターに SIO_NSP_NOTIFY_CHANGE を設定し、完了ルーチンなしで (lpCompletion パラメーターに NULL を設定して) NSPIoctl 関数を呼び出します。データが無効になった場合は、NSPLookupServiceEnd 関数を呼び出してクエリハンドルを閉じます。そして NSPLookupServiceBegin 関数を呼び出して新しいクエリハンドルを取得し、クエリを最初からやり直します。
マルチスレッドのアプリケーションでは、NSPIoctl 関数の一般的な使用方法は次のとおりです。NSPLookupServiceBegin 関数を最初に呼び出した後、dwControlCode パラメーターに SIO_NSP_NOTIFY_CHANGE を設定し、完了ルーチンを指定して NSPIoctl 関数を呼び出します。アプリケーションは、完了ルーチンで指定した通知メカニズムを使用して、データが有効でなくなったときに通知を受け取ります。一般的なメカニズムの 1 つは、完了ルーチンでイベントを指定することです。データが無効になった場合は、NSPLookupServiceEnd 関数を呼び出してクエリハンドルを閉じます。そして NSPLookupServiceBegin 関数と NSPIoctl 関数を呼び出して新しいクエリハンドルを取得し、クエリを最初からやり直します。
プロトコルによっては、単に情報をローカルにキャッシュし、一定時間後にそれを無効化するものもあります。その場合、ローカルキャッシュが無効化されたことを示す通知が発行されることがあります。
変更がまれな名前解決プロトコルでは、名前空間プロバイダーが、変更通知を要求され発行された対象のクエリには当てはまらないグローバルな変更イベントを通知する可能性があります。
即時のポーリング操作は通知オブジェクトを必要としないため、通常はリソース消費がはるかに少なくなります。多くの場合、これは単純なブール値のチェックとして実装されています。一方、非同期通知では、名前空間プロバイダーサービスの実装によっては専用のワーカースレッドやプロセス間通信チャネルの作成が必要になる場合があり、変更イベントのシグナル通知に使用される通知オブジェクトに伴う処理オーバーヘッドが発生します。
非同期通知の要求をキャンセルするには、対象のクエリハンドルに対して NSPLookupServiceEnd 関数を呼び出し、元のクエリを終了させます。LUP_NOTIFY_HWND の非同期通知をキャンセルしてもメッセージはポストされませんが、オーバーラップ操作は完了し、エラー WSA_OPERATION_ABORTED とともに通知が配信されます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)