3

IOfficeAntiVirus COM インターフェイスを使用して、Microsoft Security Essentials ウイルス スキャナーを使用したスキャンを実行しようとしています。

IOfficeAntiVirus インターフェイスは IUknown から継承され、IDispatch をサポートしていないとドキュメントに記載されているため、早期バインディングを行っています。

[Guid("56FFCC30-D398-11d0-B2AE-00A0C908FA49"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface IOfficeAntiVirus
{
    void Scan(IntPtr info);
}

[ComImport, Guid("2781761E-28E1-4109-99FE-B9D127C57AFE")]
class SecurityEssentialsAntiVirus
{
}

scan メソッドのパラメーターは、この例に由来する型です。この例は、scan メソッドを呼び出すのではなく、.NET クラスを使用して IOfficeAntiVirus インターフェイスを実装しているため、私が望んでいたこととは反対のことをしています。この例のマーシャリングと型は、私が知る限り、ドキュメントと一致しているようです。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct MSOAVINFO
{
public int cbsize;

[MarshalAs(UnmanagedType.U4)]
public uint uFlags;
public IntPtr hwnd;

[MarshalAs(UnmanagedType.LPWStr)]
public string pwzFullPath;

[MarshalAs(UnmanagedType.LPWStr)]
public string pwzHostname;

[MarshalAs(UnmanagedType.LPWStr)]
public string pwzOrigURL;
}

これは、スキャン メソッドを呼び出すために使用しようとしているコードです。

var antivirus = (IOfficeAntiVirus)new SecurityEssentialsAntiVirus();
var file = new MSOAVINFO();
file.pwzFullPath = @"test.txt";
IntPtr lParam = Marshal.AllocHGlobal(Marshal.SizeOf(file));
Marshal.StructureToPtr(file, lParam, false);
antivirus.Scan(lParam);

scan メソッドの呼び出しで失敗します。次のような例外が発生します。

「保護されたメモリの読み取りまたは書き込みを試みました。これは多くの場合、他のメモリが破損していることを示しています。」

これを 64 ビット システムの 32 ビット コマンド ライン アプリから実行しています。コマンド ライン プログラムを 32 ビットと 64 ビットの両方で実行してみましたが、成功しませんでした。

IOfficeAntiVirus GUID は、ドキュメントから取得したので、正しいと確信しています。また、COM インターフェイスではないランダムな GUID を試行すると、オブジェクトをインターフェイスにキャストしようとするとエラーが発生します。

SecurityEssentialsAntiVirus GUID が IOfficeAntiVirus を実装していることは確かです。別の種類の COM オブジェクトをそのインターフェイスにキャストしようとしたときにエラーが発生したからです。

問題は、インターフェイスの Scan メソッドが正しく宣言されていないことだと思います (インターフェイスでランダム メソッドを宣言すると、同じエラーが発生します)。私はセキュリティ エッセンシャル アセンブリのドキュメントから作業していないので、私が想像する方法で (またはまったく) インターフェイスを実装しない可能性があります。誰かがそれを確認する方法を知っていますか?

そのディレクトリに MpOAv.dll ファイルがあり、それは IOfficeAntiVirus ドキュメントのヘッダー ファイルと同じ名前です。その dll を ole-com オブジェクト ビューアで開いて中身を確認することができません。次のようなメッセージが表示されます。

IMoniker::BindToObject から作成されたファイル モニカー ( "C:\Program Files\Microsoft Security Client\MpOAv.dll" ) で失敗しました。ファイルの拡張子が正しくありません

MK_E_INVALIDEXTENSION ($800401E6)

また、構造体を Scan メソッドに正しく渡していない可能性もあります。AllocCoTaskMem() を使用したり、構造体を参照渡ししたりするなど、約 100 のバリエーションを試してみました。

私は実際に相互運用の経験があまりないので (今日、これを理解しようとしてヒープを学びました!)、正しい方向へのプッシュに本当に感謝しています。:)

4

2 に答える 2

0

私が気づいたことの 1 つは、cbsize を設定していないことです。file.cbsize=Marshal.SizeOf(ファイル);

于 2012-08-15T16:52:42.627 に答える