0

I'm having a bit of trouble getting MoveFileEx to work properly in Windows 7 x64.

I'm running my application as administrator, marking files for deletion on next reboot but after rebooting find that none of the files are being deleted.

I'm using the following to accomplish said feat:

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, MoveFileFlags dwFlags);

    private static IEnumerable<string> GetFiles(string path)
    {
        var queue = new Queue<string>();
        queue.Enqueue(path);
        while (queue.Count > 0)
        {
            path = queue.Dequeue();
            try
            {
                foreach (var subDir in Directory.GetDirectories(path))
                {
                    queue.Enqueue(subDir);
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
            }
            string[] files = null;
            try
            {
                files = Directory.GetFiles(path);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
            }
            if (files != null)
            {
                foreach (var t in files)
                {
                    yield return t;
                }
            }
        }
    }
 private void button1_Click(object sender, EventArgs e)
{
  foreach (var files in GetFiles(sysRoot + @"\system32\spool\drivers\x64\"))
  {
    Log(files);
    MoveFileEx(files, null, MoveFileFlags.MovefileDelayUntilReboot);
  }
}

I can verify the marking process is being done on multiple files, just can't figure out why it's not then performing the delete functionality after the machine has been rebooted.

Any assistance in this area will be greatly appreciated.

Thank you.

svick
  • 236,525
  • 50
  • 385
  • 514
Clu
  • 339
  • 3
  • 8
  • 18
  • Plot thickens, in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager I see a Key named PendingFileRenameOperations, in it has a list of the files but with the wrong path... "\??\C:\Windows\SysWOW64\spool\drivers\x64\3\" SysWOW64??? I don't get where windows is grabbing this from... I'm clearly specifying windows/system32 – Clu Dec 06 '11 at 02:07
  • The problem seems related to x64, on 32bit this same code runs without any issues... I cant figure out why the path is altered in PendingFileRenameOperations to SysWOW64, has anyone heard of this before? – Clu Dec 06 '11 at 02:13
  • 1
    The reason its being altered is because the directory does not actually exist on x64. WoW64 provide a transparent redirection to the correct directory. You actually want to access the x64 drivers not the x86 drivers. Furthermore PLEASE edit your question and provide updates, using comments is annoying, hard to read. – Security Hound Dec 06 '11 at 14:23
  • 1
    \\?\ at the beginning of a path is not incorrect. That's valid. See http://msdn.microsoft.com/en-us/library/aa365247.aspx – StilesCrisis Dec 07 '11 at 19:09

2 Answers2

2

You are making a pretty classic winapi mistake. You set the SetLastError property to true but then don't actually check if the function failed. Modify your code like this:

if (!MoveFileEx(files, null, MoveFileFlags.MovefileDelayUntilReboot)) {
    throw new System.ComponentModel.Win32Exception();
}

Now you'll know why it failed.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Hans, thank you for that however, even with your modified code, I'm still not seeing any exceptions being thrown. – Clu Dec 06 '11 at 01:50
1

If these are driver files that are loaded as soon as the machine boots, they might not be deletable because they are open/in-use.

StilesCrisis
  • 15,972
  • 4
  • 39
  • 62
  • Is there perhaps a different way of handling this? – Clu Dec 06 '11 at 01:51
  • @Clu - Don't use a **sysRoot + @"\system32\** because this isn't valid on x64 operating system. – Security Hound Dec 06 '11 at 14:21
  • Tried the literal path, didn't make a difference, it's still adding entries like "\??\C:\Windows\SysWOW64\spool\drivers\x64\3\mfricr64.dll" to PendingFileRenameOperations. – Clu Dec 07 '11 at 18:45
  • So if the application is compiled to 64bit, it works fine, is there anyway to make this dynamically switch based on the OS being 32bit or 64? – Clu Dec 07 '11 at 18:50