try..catch 内でストリームを読み取る IO コードがいくつかあります。IOException をキャッチし、キャッチ内でSystem.Runtime.InteropServices.Marshal.GetHRForException()を呼び出し て、HResult に基づいてさまざまなアクションを実行しようとします。このようなもの:
try
{
stream.Read(...);
}
catch (IOException ioexc1)
{
uint hr = (uint) Marshal.GetHRForException(ioexc1);
if (hr == ...)
do_one_thing();
else
do_another();
}
アセンブリは署名され、AllowPartiallyTrustedCallersAttributeでマークされています。
しかし、ASP.NET 内で trust="medium" を指定してこのコードを実行すると、次の例外が発生します。
Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
いくつかの質問:
- GetHRForException が中程度の信頼では許可されていないアンマネージ コードを呼び出すため、例外が発生していると思います。正しい?
- この例外は、GetHRForException の実行時ではなく、メソッドが JIT されているときにスローされます - 正しいですか? (スタックトレースは私の方法を示していますが、IO 例外が発生していないことは 99% 確信しています)
- その場合、許可されていない GetHRForException (アンマネージ コード) を呼び出さないように、部分信頼環境で動作を変更する方法はありますか? つまり、コードが GetHRForException() を呼び出す必要があるかどうかを実行時に評価しながら、コンパイル時に JIT を成功させるにはどうすればよいでしょうか? このようなもの:
catch (IOException ioexc1)
{
if (!OkToCallUnmanaged())
throw ioexc1;
uint hr = (uint) Marshal.GetHRForException(ioexc1);
if (hr == ...)
do_one_thing();
else
do_another();
}
アクセス許可が利用可能かどうかをテストするためのランタイム メカニズムがあると思いますが、それを見つけることができませんでした。
編集:このブログ記事は答えですか?Microsoft の ShawnFa は、LinkDemand によって保護されたメソッドの周りで try ... catch(SecurityException) を実行できないと述べています。MethodA() が MethodB() を呼び出し、MethodB() が完全信頼の LinkDemand でマークされている場合、LinkDemand は MethodA が Jit されているかどうかでチェックされます。したがって、SecurityException を回避するには、Marshal.GetHRForException を別のメソッドに抽出する必要があります。あれは正しいですか?
私のコードに適用すると、MethodA() は Read を呼び出すコードである可能性があり、キャッチで GetHRForException() を呼び出そうとします。GetHRForException は MethodB() です。LinkDemand は、MethodA() が JIT されたときに評価されます。(この LinkDemand は、信頼度が中程度の ASP.NET シナリオでは失敗します)。GetHRForException を新しいメソッド MethodC() に移動し、命令型の permission.Demand() が成功した後にのみ条件付きで MethodC() を呼び出すと、理論的には JIT 時に SecurityException を回避できるはずです。 permission.Demain() が成功した後にのみ JIT されます。