MS VC++ プロジェクトの WinAPI 関数呼び出しを独自の実装 (名前とパラメーター セットは同じ) に置き換えるにはどうすればよいですか?
-
09-06-2019 - |
質問
すべての WinAPI 呼び出しを置き換える必要があります。
- ファイルの作成、
- ファイルの読み取り、
- SetFilePointer、
- クローズハンドル
私自身の実装 (Bluetooth を介した低レベルのファイル読み取りを使用) を使用します。関数が置き換えられるコードはビデオ ファイル プレーヤーであり、すでに通常の HDD ファイルで動作します。また、VideoPlayer 入力のファイルが通常の HDD ファイルである場合、Video Player が HDD からファイルを再生できることも必要です。
このようなタスクのベストプラクティスは何ですか?
解決
次の手順に従うことをお勧めします。
- MyCreateFile、MyReadFile など、最初は対応する API を呼び出し、同じ引数を変更せずに渡すだけのラッパー関数のセットを作成します。
- テキスト エディターを使用して、元の API へのすべての呼び出しを検索し、これらを新しいラッパー関数への呼び出しに置き換えます。
- アプリケーションが引き続き正しく機能することをテストします。
- 独自の目的に合わせてラッパー関数を変更します。
CreateFile は、UNICODE が定義されているかどうかに応じて、CreateFileW または CreateFileA に展開されるマクロであることに注意してください。LPCTSTR と TCHAR関数 これにより、アプリケーションを ANSI または Unicode として構築できるようになります。
ここの他の回答で示唆されているように、 #define は使用しないでください。これはメンテナンスの問題を引き起こすだけであり、Maximilian が正しく指摘しているように、ベストプラクティスではありません。
他のヒント
新しい関数をカスタム名前空間に記述するだけです。例えば
namespace Bluetooth
{
void CreateFile(/*params*/);
void etc...
}
コード内で変更する必要があるのは次の点だけです。
if (::CreateFile(...))
{
}
に
if (Bluetooth::CreateFile(...))
{
}
簡単!:)
別のアプリケーションからこれらの API への呼び出しをインターセプトしようとしている場合は、次のことを検討してください。 迂回路.
コードを編集できる場合は、必要なことを実行するカスタム API を使用するようにコードを書き直すだけです。それに失敗した場合は、マクシミリアンのテクニックを使用しますが、それはメンテナンスの恐怖であることに注意してください。
コードを編集できない場合は、インポート テーブルにパッチを適用して、呼び出しを独自のコードにリダイレクトできます。このテクニックの説明は、次の場所にあります。 この記事 - 「インポート アドレス テーブルの変更によるスパイ」というタイトルのセクションを検索します。
これは危険ですが、注意していればうまくいくでしょう。こちらもチェックしてください マイクロソフトの迂回路, 、同じようなことを行いますが、実際のパッチをいじる必要はありません。
本当に API をハイジャックしたい場合は、以下を参照してください。 注射器.dll (L-GPL)。
これがベストプラクティスとは思えませんが、変更したい関数が呼び出される場所にインクルードファイルに含めればうまくいくはずです。
#define CreateFile MyCreateFile
HRESULT MyCreateFile(whatever the params are);
MyCreateFile の実装は次のようになります。
#undef CreateFile
HRESULT MyCreateFile(NobodyCanRememberParamListsLikeThat params)
{
if (InputIsNormalFile())
CreateFile(params);
else
// do your thing
}
基本的に、すべての CreateFile 呼び出しを MyCreateFile 呼び出しにし、独自の実装を使用する必要があるか、オリジナルの実装を使用する必要があるかを決定できます。
免責事項:こんなことをするのは醜いことだと思いますし、私ならやりません。すべての出現箇所を検索して置換するか何かをしたいと思います。