インターネットを検索したところ、プロセスがファイルに書き込めるかどうかを判断する 2 つの方法が見つかりました。権限を確認し、書き込みを試みます。この 2 つを試してみることにしましたが、驚くべき結果が得られました。
ファイルのセキュリティ権限を確認すると、プロセスが昇格モードで実行されているかどうかに関係なく、プロセスが UAC で保護されたディレクトリ内のファイルへの書き込みアクセス権を持っていることが報告されているようです。一方、書き込み試行 (System.IO) を使用すると、プロセスが昇格モードで実行されている場合にのみ、プロセスが UAC で保護されたディレクトリ内のファイルへの書き込みアクセス権を持つことが報告されます。
私の質問は次のとおりです。
- セキュリティ権限のアプローチを使用すると、なぜ間違った結果が得られるのですか?
- 実際の書き込み試行の代わりにセキュリティ権限を使用したいのはどのような場合ですか?
テストに使用したコードは次のとおりです。
using System;
using System.IO;
using System.Security;
using System.Security.Permissions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
foreach (var filename in new[]{@"C:\Windows\win.ini",
Environment.ExpandEnvironmentVariables(@"%tmp%\temp.txt")})
{
Console.WriteLine("File Name: {0}", filename);
Console.WriteLine("Write Permission : {0}", WriteAccess(filename));
Console.WriteLine("IO Write Attempt : {0}", WriteAccess2(filename));
Console.WriteLine();
}
var principal = System.Threading.Thread.CurrentPrincipal;
Console.ReadLine();
}
static bool WriteAccess(string filename)
{
var permissionSet = new PermissionSet(PermissionState.None);
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Write, filename));
return permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet);
}
static bool WriteAccess2(string filename)
{
try
{
// assumes the file exists
using (var fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite))
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
}
}
出力 (昇格されていないプロセス)
ファイル名: C:\Windows\win.ini 書き込み許可: True IO 書き込み試行: False ファイル名: C:\Users\Alex\AppData\Local\Temp\temp.txt 書き込み許可 : True IO 書き込み試行: True
アウトプット(昇格したプロセス)
ファイル名: C:\Windows\win.ini 書き込み許可 : True IO 書き込み試行 : True ファイル名: C:\Users\Alex\AppData\Local\Temp\temp.txt 書き込み許可 : True IO 書き込み試行: True