在 c# 中使用 WMI 获取UWF_Filter状态时接收访问被拒绝



我正在尝试以用户身份获取Windows 10 IoT中UWF Wilter的状态。我正在使用以下代码:

private void Form1_Load(object sender, EventArgs e)
{
try
{
ConnectionOptions Options = PrepareOptions();
ManagementScope scope = new ManagementScope();
scope.Path = new ManagementPath(@"\localhostrootStandardCimv2embedded");
scope.Options = Options;
scope.Connect();
using (ManagementClass mc = new ManagementClass(scope.Path.Path, "UWF_Filter", null))
{
//next line failes with Access Denied under normal user account
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
string UWFstate = (bool)mo.GetPropertyValue("CurrentEnabled");
if ( UWFstate )
{
// Do Something When Enabled
}
else
{
// Do Something Else When Disabled
}
}
}
}
catch (Exception ex)
{
trow;
}
}       

public static ConnectionOptions PrepareOptions()
{
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = ImpersonationLevel.Impersonate;
options.Authentication = AuthenticationLevel.Default;
options.EnablePrivileges = true;
return options;
}

当我尝试在普通用户帐户下运行此代码并启用写入过滤器时,getinstances(( 方法返回拒绝访问。禁用写入筛选器后,代码运行良好。此外,在管理用户下运行时,它可以完美运行。

当我使用 PowerShell 尝试此操作时,我还会收到一条拒绝访问消息。

MSDN 的 UWF_Filter 类文档指出:

必须使用管理员帐户对 UWF 的配置设置进行任何更改。拥有任何类型的帐户的用户都可以读取当前配置设置。

因此,我认为普通用户必须能够读取UWF配置。还是我在某处犯了错误?

知道吗?

谢谢米歇尔。

我遇到了同样的问题。经过如此多的研究,最终发现WMI甚至不提供管理员在UWF_Volume中编写排除项的访问权限(通过PowerShell,C#,C++从管理员帐户尝试(,而UWF_Filter.Enable((,UWF_Filter.Disable((和其他一些方法正常工作。 因此,为了添加排除项,我使用了程序中的命令工具。

如果只想知道 UWF 筛选器是否打开,可以使用解决方法:

unit osWMIUtils;
interface
type
TWMI_UWF_Filter = record
const
RC_EMPTY            = 0;
RC_HAS_DATA         = 1;
RC_ACCESS_DENIED    = 2;
RC_INVALID_CLASS    = 3;
RC_GENERIC_ERROR    = 4;
public
ResultCode: Integer;
CurrentEnabled: Boolean;
NextEnabled: Boolean;
procedure Init;
end;
function GetUWFFilterInfo: TWMI_UWF_Filter;
implementation
uses
System.SysUtils,
System.Variants,
System.Win.ComObj,
Winapi.Wbem,
Winapi.ActiveX;
{ TWMI_UWF_Filter }
procedure TWMI_UWF_Filter.Init;
begin
ResultCode := RC_EMPTY;
CurrentEnabled := False;
NextEnabled := False;
end;
{ generic functions }
{**
*  TAKE CARE
*  =========
*  Unified Write Filter (UWF) info are available ONLY if installed and in following Windows versions:
*    Windows xx Enterprise
*    Windows xx Education
*    Windows xx IoT Core Enterprise
*
*  so if you take a query of 'UWF_Filter' on an unsupported Windows version a WBEM_E_INVALID_CLASS will be raised.
*
*  If Unified Write Filter (UWF) is available but not active (CurrentEnabled = False) the query returns the actual
*  values of CurrentEnabled/NextEnabled with following code executed at any priviledges level.
*
*  If Unified Write Filter (UWF) is available and active (CurrentEnabled = True) the query returns the actual
*  values of CurrentEnabled/NextEnabled only with code executed with Administrator prividedges otherwise raises a
*  WBEM_E_ACCESS_DENIED exception.
*
*  TWMI_UWF_Filter.ResultCode:
*    RC_EMPTY            = There are not evaluated data yet.
*    RC_HAS_DATA         = UWF Filter available and data aligned with UWF Filter settings.
*    RC_ACCESS_DENIED    = UWF Filter available and active. NextEnabled info is not accessible.
*    RC_INVALID_CLASS    = UWF Filter not available. CurrentEnabled/NextEnabled to False by default.
*    RC_GENERIC_ERROR    = UWF Filter cannot be detected for an error. CurrentEnabled/NextEnabled to False by default.
*
**}
function GetUWFFilterInfo: TWMI_UWF_Filter;
const
WbemUser            = '';
WbemPassword        = '';
WbemComputer        = 'localhost';
WbemFlagForwardOnly = $00000020;
var
IValue: LongWord;
OEnum: IEnumvariant;
FWMIService: OLEVariant;
FWbemObject: OLEVariant;
NeedUninitialize: Boolean;
FSWbemLocator: OLEVariant;
FWbemObjectSet: OLEVariant;
begin;
Result.Init;
try
NeedUninitialize := CoInitialize(nil) = S_OK;
try
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'rootStandardCimv2embedded', WbemUser, WbemPassword);
FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM UWF_Filter','WQL', wbemFlagForwardOnly);
OEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
while OEnum.Next(1, FWbemObject, IValue) = 0 do
begin
Result.CurrentEnabled := FWbemObject.CurrentEnabled;
Result.NextEnabled := FWbemObject.NextEnabled;
Result.ResultCode := TWMI_UWF_Filter.RC_HAS_DATA;
end;
FWbemObject := Unassigned;
finally
if NeedUninitialize then
CoUninitialize;
end;
except
on E: EOleException do
begin
Result.Init;
case E.ErrorCode of
WBEM_E_ACCESS_DENIED:
begin
Result.ResultCode := TWMI_UWF_Filter.RC_ACCESS_DENIED;
Result.CurrentEnabled := True;
Result.NextEnabled := False;
end;
WBEM_E_INVALID_CLASS:
begin
Result.ResultCode := TWMI_UWF_Filter.RC_INVALID_CLASS;
Result.CurrentEnabled := False;
Result.NextEnabled := False;
end;
else
begin
Result.ResultCode := TWMI_UWF_Filter.RC_GENERIC_ERROR;
Result.CurrentEnabled := False;
Result.NextEnabled := False;
end;
end;
end;
on E: Exception do
begin
Result.ResultCode := TWMI_UWF_Filter.RC_GENERIC_ERROR;
Result.CurrentEnabled := False;
Result.NextEnabled := False;
end;
end;
end;
end.

最新更新