Thank you again for your time. I'll try to clarify a couple of points from my rushed last post
Here's how I see the situation.
Firstly, MoveFileEx with any other argument combination works perfectly.
Let's now make the assumption that automatic file system redirection (SysWOW64 & Sysnative redirection which works in every case...except across a reboot) works at the lowest level, so that the code is not duplicated. I am going to pretend (and I recognise that this is highly unlikely to be factually accurate, that this redirection occurs in a file system filter driver. This is just so I can save myself some typing later (you'll soon see why). So...FSR occurs in a driver. Please bear with me.)
When you call MoveFileEx to make the move now, the call sinks lower and lower until hitting the FS driver layer, and directory redirection comes into play when the FSR driver is called. Everything works well.
However, when you call MoveFileEx to make the replacement over the reboot, the function BasepMoveFileDelayed gets called, which sets the path into the PendingFileRenames registry value for processing over the reboot. Because no file is being moved now, the FSR driver never gets called, and so no redirection takes place. There is no automatic redirection, and the registry value gets set to exactly the string which is passed in. Happy so far?
So, e.g. if I call System32 from a WOW64 process, System32 gets written to the registry.
Now, over the reboot, the actual replacement is made by smss.exe. This is a 64bit process. Therefore, when it makes the move, redirection policies act as though it were a 64bit application. So System32 --> System32, SysWOW64 --> SysWOW64, Sysnative --> X
This works fine, but there's a critical problem. I passed System32 to MoveFileEx from my WOW64 process. This got left as System32 in the registry, and so eventually got redirected as System32 --> System32 from a 64bit process. This is not how the rest of the OS works. Under any other conditions, WOW64 System32 --> SysWOW64, which did not occur here. The automatic redirection policies simply do not work due to the transition from 32bit to 64bit process in the middle.
Fortunately, Microsoft recognised that there MUST be additional manual redirection to fix this issue (basically, to flip all of the redirections to transition from 32bit to 64bit). So they had two choices, redirection in smss.exe, or redirection in BasepMoveFileDelayed.
Let's first consider the possibility of redirection in smss.exe:
Let's consider how the registry gets set:
64bit Process: Passed in: System32: Where File Should End Up: System32
64bit Process: Passed in: SysWOW64: Where File Should End Up: SysWOW64
64bit Process: Passed in: Sysnative: Where File Should End Up: X
WOW64 Process: Passed in: System32: Where File Should End Up: SysWOW64
WOW64 process: Passed in: SysWOW64: Where File Should End Up: X
WOW64 process: Passed in: Sysnative: Where File Should End Up: System32
So...the smss.exe redirection needs to be as follows (top to bottom):
System32 --> System32 (no direction)
SysWOW64 --> SysWOW64 (no redirection)
System32 --> SysWOW64
Sysnative --> System32
But look at the red...there's a conflict. Depending on whether a 64bit or WOW64 bit process created the PendingFileRenames key, the redirection needs to vary. But this information is not saved. There is no way to overcome this (without changing the structure of the PendingFileRenames key), so redirection within smss.exe must be ruled out.
So...the alternative: redirection in BasepMoveFileDelayed before putting the data into the registry. Here, the bitness of the process is known, and that's very important.
The same redirections need to occur, but the bit-rate is known.
System32 --> System32 (if 64bit process)
SysWOW64 --> SysWOW64 (if 64bit process)
System32 --> SysWOW64 (if WOW64 process)
Sysnative --> System32 (if WOW64 process)
Therefore, this comes down to:
System32 --> SysWOW64 (if WOW64 process)
Sysnative --> System32 (if WOW64 process)
as no redirection is required for 64bit processes. So I looked at the code for BasepMoveFileDelayed, and I found this rule:
System32 --> SysWOW64 for WOW64 processes. And that is correct. But we've also ascertained already that there must also be a Sysnative redirection rule. And there simply isn't.
This, almost without any doubt at all, is a bug in BasepMoveFileDelayed. Would you agree?
Richard
P.S. The only thing I haven't yet quite got straight is why Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection DOES work as a fix/workaround for this issue. I'm still investigating where the normal redirection takes place and how it fits into the above.