简体   繁体   中英

UWF_Volumes has no entries with CurrentSession=False

since some time now I try to figure out how to correctly setup this new UWF (Unified Write Filter). Unfortunately it seems there is only documentation for Win 8.1 industry ( here ), not for Win 10. I hope there were no relevant changes since.

I also asked this on the WindowsDevCenter but got no response so far.

Here is my problem:

With the WMI providers I got UWF enabled by now ( UWF_Filter.Enable() ), but I cannot protect any volume.

Also the volume list looks very strange: There are 4 entrys, everyone is with CurrentSession=True .

  • The first is for an volume with no drive letter, only a volume id.
  • The second is for C:
  • and then there are 2 identical for D: .

Should'nt there normally be 2 entrys per volume, one where CurrentSession is true and one where its false, meaning its the setting applied after reboot?

If I try to execute Protect on the ManagementObject with DriveLetter=C: I get an Access denied exception, I assume because its the object for the current session.

Also if I try uwfmgr.exe Volume Protect C: on the console it simply hangs: no reaction, no error, only a forever blinking cursor. EDIT: it turned out this was a problem caused by another installed software. See also below.

Do I have to enable or disable or do anything else before I can protect volumes?

Thanks in advance,

Sebastian

My system:

  • Windows 10 IOT Enterprise 2016 LTSB x64
  • 1 SSD 250GB with Boot, C: and D:

Edit:

Here I asked a follow up question with some other details and a workaround. If I use uwfmgr.exe volume protect c: for example, it works and UWF_Volume now suddenly has (the correct) 2 entries for C: , one for the current and one for the next session.

However I want to avoid this, because IMHO it should be solveable by WMI only.

Edit 2: @sommmen

The partition layout is as following: One disk with 4 partitions.

  1. Boot, 500MB
  2. C:/ , 45GB
  3. unknown, 500MB (Boot-Backup I think)
  4. D:/ , ~200GB

PS:

Please could anyone create the tags uwf and uwfmgr ? Would be nice :-)

Missing UWF_Volume instances often appeared after reboot in my tests. But if not, you can create them directly using ManagementClass.CreateInstance() .

The problem here is that the official docs are not exactly correct. The description of the UWF_Volume.VolumeName property is:

The unique identifier of the volume on the current system. The VolumeName is the same as the DeviceID property of the Win32_Volume class for the volume.

from: https://docs.microsoft.com/en-us/windows-hardware/customize/enterprise/uwf-volume#properties

In fact, the DeviceID needs a slight modification, before using it as value for UWF_Volume.VolumeName :

DeviceID.Substring(4).TrimEnd('\\')

So, after removing prefix \\\\?\\ and removing any trailing slashes you can create instances with CurrentSession=false for the specified device.

This also works in Windows 10 Pro without any uwfmgr.exe . Though, officially not recommended/supported.

Also, I was not able to delete instances, yet. So be sure to add only correct values.

Full Example:

// example value
var DeviceId_From_Win32_Volume = @"\\?\Volume{c2eac053-27e3-4f94-b28c-c2c53d5f4fe1}\";

// example value
var myDriveLetter = "C:"; 
var myDeviceId = DeviceId_From_Win32_Volume.Substring(4).TrimEnd('\\'); 

var wmiNamespace = "root\\standardcimv2\\embedded";
var className = "UWF_Volume";

var mgmtScope = new ManagementScope {Path = {NamespacePath = wmiNamespace}};
var mgmtPath = new ManagementPath(className);
var mgmtClass = new ManagementClass(mgmtScope, mgmtPath, null);

// prepare the new object
var newObj = mgmtClass.CreateInstance();
newObj.SetPropertyValue("DriveLetter", myDriveLetter);
newObj.SetPropertyValue("VolumeName", myDeviceId);
newObj.SetPropertyValue("CurrentSession", false);
newObj.SetPropertyValue("CommitPending", false);
newObj.SetPropertyValue("BindByDriveLetter", false);

// create the WMI instance
newObj.Put(new PutOptions {Type = PutType.CreateOnly});

I experience the similar issue in that I could not query the UWF_Volume with CurrentSession=False. However, there's one thing I did that seems to "generate" the UWF_Volume management object with CurrentSession=False. I ran "uwfmgr volume protect c:". Unfortunately, in your case running this causes it to hang.

Could you try running uwfmgr in cmd in admin? Also, if you run "uwfmgr get-config", would you be able to get the current setting of the write filter?

Another thing from your description: you said there are two identical volumes for D:, but if you looks closely at the properties, one would be CurrentSession=True, and the other one is CurrentSession=False. According to the documentation, if you want to make change, you must select the management object (UWF_Volume) with CurrentSession=False.

https://docs.microsoft.com/en-us/windows-hardware/customize/enterprise/uwf-volume

(scroll down to powershell script code sample section)

First of all a volume may have several partitions. They will show up as having the same drive label.

eg

C:/ //?/{some guid here}
C:/ //?/{some other guid here}

Now this is common for the %systemDrive% because this has the boot partition. You can use the commands

mountvol

and

Diskpart
List volume

To figure out the right guid for your need (or you can protect both the boot partition and the system partition). Also using wmi you can look at Win32_volume under namespace cimv2 to get some more insight.

The command line util UWFmgr seems to create an UWF_VOLUME wmi instance once you run the protect command. The docs also hint that you need to create an object yourself.

function Set-ProtectVolume($driveLetter, [bool] $enabled) {

# Each volume has two entries in UWF_Volume, one for the current session and one for the next session after a restart
# You can only change the protection status of a drive for the next session

    $nextConfig = Get-WMIObject -class UWF_Volume @CommonParams |
        where {
            $_.DriveLetter -eq "$driveLetter" -and $_.CurrentSession -eq $false
        };

# If a volume entry is found for the drive letter, enable or disable protection based on the $enabled parameter

    if ($nextConfig) {

        Write-Host "Setting drive protection on $driveLetter to $enabled"

        if ($Enabled -eq $true) {
            $nextConfig.Protect() | Out-Null;
        } else {
            $nextConfig.Unprotect() | Out-Null;
        }
    }

    =======> (!) im talking about this comment
# If the drive letter does not match a volume, create a new UWF_volume instance

    else {
    Write-Host "Error: Could not find $driveLetter. Protection is not enabled."
    }
}

The docs however do not provide a method of doing this. For now it seems we need to use the command line util till someone has an example using the WMI provider.

To answer my own question: So far I have only a workaround but no real solution.

It is to check if there is an entry with CurrentSession=False and if not invoke the command directly:

ManagementObjectSearcher ms = new ManagementObjectSearcher(_Scope, new ObjectQuery("select * from UWF_Volume where VolumeName = \"" + volId + "\" AND CurrentSession=\"False\""));
ManagementObjectCollection c = ms.Get();
UInt32 res = 1;
foreach (ManagementObject mo in c)
{
    // entry found: do it with WMI
    res = (UInt32)mo.InvokeMethod(newState ? "Protect" : "Unprotect", new object[] { });
}
if (c.Count == 1 && res == 0)
    // message: success
if (c.Count == 0)
{
    // no entry found: invoke cmd
    ProcessStartInfo info = new ProcessStartInfo("uwfmgr.exe", "volume " + (newState ? "Protect" : "Unprotect") + @" \\?\" + volId);
    Process process = new Process();
    info.Verb = "runas";  //needs admin
    process.StartInfo = info;
    process.Start();
    process.WaitForExit();
}

This has the side effect that for a split second a command line window will pop up, but nevertheless it works well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM