-1

I would like to know whether anyone can explain a reason for ReOpenFile failing with "error-invalid-name", when CreateFile has successfully opened the file.

Here are the details:

I open a file C:\Windows\system32\unit_test.txt using CreateFile, and it opens fine. When I later attempt to change permissions using ReOpenFile, this fails with error code 123 (decimal) which the debugger shows as "ERROR_INVALID_NAME: The filename directory name or volume label syntax is incorrect".

ReOpenFile works fine if "unit_test.txt" is placed in a more conventional directory. ReOpenFile does not take a filename parameter, but rather the handle that is returned from CreateFile. The code that I have written is not requesting additional privileges nor conflicting privileges (which results in a different error), so I am curious as to why CreateFile would succeed and ReOpenFile fail in this one situation.

Admittedly the placing of the file in Windows\System32 was accidental, but if I can do it by accident, then a user of our software might stumble upon the same issue.

I have since created this example using identical function calls, but I can't get it to fail. It shows essentially what had been producing the error though:

int main ()
{
HANDLE h1 = ::CreateFile (_T("c:\\windows\\system32\\test.txt"),
                          GENERIC_READ | GENERIC_WRITE | DELETE,
                          FILE_SHARE_READ,
                          nullptr,
                          CREATE_ALWAYS,
                          FILE_FLAG_SEQUENTIAL_SCAN,
                          NULL);

if (h1 != INVALID_HANDLE_VALUE)
{
    HANDLE h2 = ::ReOpenFile (h1,
                              GENERIC_READ,
                              FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                              FILE_FLAG_SEQUENTIAL_SCAN);

    ::CloseHandle (h1);

    if (h2 != INVALID_HANDLE_VALUE)
        ::CloseHandle (h2);
}
}
Coder_Dan
  • 1,815
  • 3
  • 23
  • 31
  • 2
    How about you extract a [mcve] and provide that as part of your question? – Ulrich Eckhardt Sep 28 '20 at 21:28
  • 3
    There are various protections and indirections applied to some of the Windows folders. This can cause API calls to fail in those folders when they work fine on other folders. – 1201ProgramAlarm Sep 28 '20 at 21:36
  • Did you check that `CreateFile()` was OK without any errors? – πάντα ῥεῖ Sep 28 '20 at 21:41
  • Yes - CreateFile returned a valid handle – Coder_Dan Sep 28 '20 at 21:45
  • @1201ProgramAlarm - So, most likely this issue is specific to a few protected Windows folders, rather than being a more general problem that might affect any folder with a particular attribute (like 'hidden' or 'system') or restricted access rights? – Coder_Dan Sep 28 '20 at 21:50
  • _Admittedly the placing of the file in Windows\System32 was accidental, but if I can do it by accident, then a user of our software might stumble upon the same issue._ That's unlikely. That directory is write-protected to non-admin users / non-elevated processes. – Paul Sanders Sep 28 '20 at 22:21
  • 1
    If a process can create a file in "%SystemRoot%\System32", then it can reopen it relative to the handle, unless prevented by the data-access sharing mode or delete state of the file. Something else is going on here, but without code that reproduces the problem, only someone with mystical powers can help you. – Eryk Sun Sep 28 '20 at 22:59

1 Answers1

1

As soon as I recompiled my "minimal example" as 32-bit rather than 64-bit, it started to exhibit the problem of ReOpenFile failing.

This lead me to an article that explains the situation: Accessing files from System32 directory using 32 bit application on 64 bit machine

Quote from the article: " As you seen, on a computer that is running a 64-bit version of Windows Server 2003 or of Windows XP, a 32-bit application cannot access the following folder: %WinDir%\System32

This behavior occurs because Windows on Windows 64-bit (WOW64) provides file system redirection. In a 64-bit version of Windows Server 2003 or of Windows XP, the %WinDir%\System32 folder is reserved for 64-bit applications. When a 32-bit application tries to access the System32 folder, access is redirected to the following folder:

%WinDir%\SysWOW64

By default, file system redirection is enabled.

As a walk-around solution, 32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access. "

Sadly the fact that the 32-bit application cannot fully access the directory does not stop Microsoft Windows from setting it as the working directory for the application in certain situations that I'm not fully aware of (possibly relating to sandboxing in more recent versions of Windows).

Coder_Dan
  • 1,815
  • 3
  • 23
  • 31