开发者

How to get the PendingFileRenameOperations count?

I would like to get the count of PendingFileRenameOperations, I have the following code below, but I keep getting a count higher then the actual number set in the registry.

For example, with the function below I get a count of (5) but there is only (2) pending or I get a count of (11) but there is only (5) pending.

Any help would be greatly appreciated.

function GetPendingFileRenameCount(): Integer;
const
  PendingFileRenameOperationsKey = 'SYSTEM\CurrentControlSet\Control\Session Manager';
  PendingFileRenameOperationsName = 'PendingFileRenameOperations';
var
  Reg: TRegistry;
  DataSize: Integer;
  Buffer: string;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;

    Result := 0;
    if Reg.OpenKeyReadOnly(PendingFileRenameOperationsKey) then
    begin
      DataSize := Reg.GetDataSize(PendingFileRenameOperationsName);
      SetLength(Buffer, DataSize);
      Reg.ReadBinaryData(PendingFileRenameOperationsName, Buffer[1], DataSize);
      while (Pos(#0, Buffer) > 0) do
      begin
        Result := Result + 1;
        Buffer := Copy(Buffer, Pos(#0, Buffer) + 1, Length(Buffer));
      end;
    end;
  finally
 开发者_开发问答   Reg.Free();
  end;
end;

UPDATE

I should have mentioned I'm trying to get the count of the pending files to be deleted.

UPDATE TWO

Here's what I have in my registry:

\??\Z:\Local Settings\Internet Files\Content.IE5\index.dat#0#0

\??\Z:\Local Settings\Internet Files\Content.IE5\index.dat#0#0

\??\Z:\Local Settings\Temp\etilqs_vTXZjJASQeyi046Mjjig#0#0

\??\Z:\Local Settings\Temp\etilqs_av9VVc5fw7Za76J12NTc#0#0

\??\Z:\Local Settings\Internet Files\Content.IE5#0#0

\??\Z:\Local Settings\Internet Files\Content.IE5#0#0

\??\Z:\Local Settings\Internet Files\Content.IE5\index.dat#0 !\??\z:\test.fil#0

\??\Z:\Local Settings\Internet Files\Content.IE5#0#0

\??\Z:\Local Settings\Internet Files\Content.IE5\index.dat#0 !\??\X:\test.fil#0

\??\Z:\Local Settings\Internet Files\Content.IE5#0#0

\??\Z:\Local Settings\Internet Files\Content.IE5\index.dat#0 !\??\X:\test.fil#0

\??\Z:\Local Settings\Internet Files\Content.IE5#0 !\??\X:\test.fil#0#0

The lines with the double null at the end are the files that will be deleted on the next reboot, Those are the ones I would like to get the count of (except the very last double null). I'm really not sure how to parse this to get what I'm looking for.

Would it be as simple as just adding another #0 to the Pos function?

while (Pos(#0#0, Buffer) > 0) do
begin
  Result := Result + 1;
  Buffer := Copy(Buffer, Pos(#0#0, Buffer) + 1, Length(Buffer));
end;


The registry value you're reading consists of pairs of names. Each rename operation has the old name and the new name of the file.

Notice how the value you get and the value you expect are related by the equation y = 2x + 1. The 2x component is explained by the two names for each operation. You're also counting the empty string at the end of the list, so that explains the +1 component.


PendingFileRenameOperations does work in pairs of lines.

For simplicity, let’s consider line 1 in the Source and line 2 of the Destination. The Source line starts with the Separator \??\, while the Destination might start with !\??\ or a NULL value.

The \??\ line is always present, and it can rename to something (!\??\) or to nothing (NULL value), which deletes the Source.

If renaming a File or Folder, then you would have something like this

 \??\C:\ThisIs_a\File_ThatExists\Somewhere123\intheComputer.tmp

or this

 !\??\C:\IWantTo\USethePrevious\FileorForderName\ToCreateOverRight\ThisOtherFileFolder.dll

If deleting a file or folder:

\??\C:\I_Have_this\FileOrFolder_that\Ineed\toDelete

NULL (Note: in RegEdit you will only see a blank line)

If you look at the binary values of this key, you can see the NULL value there, composed of four zeroes.

Depending on what script language you use to retrieve the data inside the value, it will treat and present the NULL value different.

I used PowerShell in this script to retrieve the Data Values of PendingFileRenameOperations. I have added comments in the script trying to make clear what is going on. It counts how many \??\ minus !\??\ to know how many files will be deleted. It also counts the NULL values. These get added when the array breaks the line.

<!-- language: powershell -->
$RebootPendingPathKey = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$RebootPendingValueName = "PendingFileRenameOperations" #Value Name

function RegistryQuery ($Path, $Value)
{
  try
  { 
    if(get-itemproperty -path $Path -ErrorAction SilentlyContinue)
    { #Checks if the Key/Path exists,
      return (get-itemproperty -path $Path -ErrorAction SilentlyContinue).$Value
    } #if the path exists, then gets the value of the key
  } catch
  {
    write-host "Error Message from Registry Query $_"
  }
}

function CountOfDeletedReplacedFiles($CombinedKeys)
{
  [array]$CombinedKeysWithAddedNull = @()
  $ReplaceCount = $DeleteCount = $NullCount = 0
  foreach($key in $CombinedKeys)
  {
    #If there is a gap in betweenlines it will be replaced with a Null value
    if(!($key -eq ""))
    {
      #If ! (excalmation mark) is found in the first element of the string then the file will be replaced
      if($key[0] -eq "!")
      {
        #It counts files to be replaced
        $ReplaceCount++
      } else
      {
        #It counts files to be deleted
        $DeleteCount++
      }
      #Adds the original value to the new array
      $CombinedKeysWithAddedNull += $key
    } else
    {
      #Add Null values when there is a space present
      $CombinedKeysWithAddedNull += $NULL
      #Counts Null values added to the CombinedKeysWithAddedNull
      $NullCount++
    }
  }
  #These lines are just for debugging purposes
  write-host "CombinedKeys elements in Incoming Array:"  $CombinedKeys.count
  write-host "CombinedKeysWithAddedNull elements in Array: "  $CombinedKeysWithAddedNull.count
  write-host "Number of Null values added: "  $NullCount
  write-host "Replace File Count: "  $ReplaceCount
  write-host "Delete File Count: "  $DeleteCount
  write-host "Number of Files to be actually deleted: " ($DeleteCount - $ReplaceCount)
  return $CombinedKeysWithAddedNull #Return Array with Nulls in case you need to set this value in a backup key
}
[array]$PendingKey = RegistryQuery $RebootPendingPathKey $RebootPendingValueName
[array]$Merged = CountOfDeletedReplacedFiles $PendingKey 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜