0

私はIcmpSendEcho2 の MSDN ドキュメントを読んでいますが、回答よりも多くの疑問が生じます。

私は、次のような他の Win32 API からの非同期コールバックに精通していますReadFileEx... 操作が 以外の結果で完了するまで、ドライバーが使用するために予約されることを保証するバッファーを提供しますIO_PENDING。失敗します (そして、GetCompletionStatusどれを見つけるために呼び出します)。タイムアウトは私の責任であり、CancelIo処理を中止するために呼び出すことができますが、ドライバーが操作をキャンセルし、完了ルーチンをステータスで呼び出すまで、バッファーは予約されたままですCANCELLED。そして、OVERLAPPEDこれらすべてを通じてリクエストを一意に識別する構造があります。

IcmpSendEcho2OVERLAPPED非同期リクエストにコンテキスト構造を使用しません。また、ドキュメントは、ping がタイムアウトまたは失敗した場合に何が起こるかについて、過度に最小限で不明確です(失敗は、ネットワーク接続の欠如、ローカル ピアの ARP エントリの欠落、リモート ピアの介在ルーターからの ICMP 宛先到達不能応答などです)。

タイムアウトや失敗時にコールバックが発生するかどうかを知っている人はいますか? 特に、応答がない場合、バッファを別の呼び出しに再利用できますか、IcmpSendEcho2または応答が遅れた場合に備えて永久に予約されますか?

私は Win32 サービスからこの関数を使用したいと考えています。つまり、エラー処理のケースを正しく取得する必要があり、バッファーをリークすることはできません (または、API がバッファーをリークする場合は、ヘルパー プロセスを使用する必要があるため、リクエストを放棄する方法があります)。

コールバックが行われる方法には、醜い非互換性もあります。PIO_APC_ROUTINE最初のパラメーターは 2 つの署名間で一致しているように見えるので、OS バージョン チェックで Vista 以降が返された場合にのみ 2 番目のパラメーターを使用する限り、新しい方を使用できるはずですか? MSDN は「Windows のバージョン チェックを行わないでください」と言っていますが、新しい引数を持つバージョンのセットは、iphlpapi.dll に関数が存在するバージョンのセットと同じではないため、そうする必要があるようです。

この関数と APC を使用する追加のドキュメントまたは作業コードへのポインターは大歓迎です。

これが完全に間違ったアプローチであるかどうかも教えてください。つまり、生のソケットを使用するか、++ の組み合わせを使用するIcmpCreateFile方がより堅牢である場合です。WriteFileExReadFileEx

4

1 に答える 1

1

コールバックではなくイベントで使っIcmpSendEcho2ていますが、流れはどちらも同じだと思います。内部でIcmpSendEcho2使用します。NtDeviceIoControlFileICMP 関連のエラーを早い段階で検出し、12xx の範囲のエラー コードとして返します。IcmpSendEcho2が返された場合 (およびその場合のみ) 、ping が成功したか、失敗したか、タイムアウトしたかに関係なくERROR_IO_PENDING、最終的にコールバックを呼び出したり、イベントを設定したりします。渡すバッファはそれまで保持する必要がありますが、後で再利用できます。

RegisterWaitForSingleObjectバージョン チェックについては、APC コールバックの代わりにイベントを使用することで、わずかなコストで回避できます。

于 2011-03-14T16:08:09.443 に答える