0

I have to read from a file that's stored in the Windows directory, either in System32 or SysWOW64. Why it's stored there and which one it ends up in is not up to me, but I check the registry to get a string that represents the valid path. It's commonly C:\Windows\System32\FileName.Sys

I long ago wrote a wrapper to handle reading this for me, which up until recently worked fine. But when I upgraded a project to use VS2013 and set the 'Prefer 32-bit' flag, the file check suddenly started returning false

if (!File.Exists(sysFilePath)) throw new FileNotFoundException(....

When I turn off the flag it starts working again. The file it's looking for is definitely there, which makes me think there's some kind of permissions issue. Running this as an admin had no effect, the file check still returned false.

Is anyone aware of changes to permissions to access System32 if an application is built AnyCPU with Prefer 32-bit checked, versus without it? Or perhaps is .NET or Windows doing something under the hood that is looking in a different directory than I specify?

cost
  • 4,420
  • 8
  • 48
  • 80
  • Difference is likely in x86 vs x64 process rather than permissions. There are all sorts of redirects for x86... – Alexei Levenkov Aug 19 '15 at 18:43
  • @AlexeiLevenkov That literally just occurred to me as you said that. Could something be automatically changing System32 to... well, isn't System32 where prefer 32 bit would want to look? – cost Aug 19 '15 at 18:45

1 Answers1

1

Seems that you are trying to run the compiled binary on 64-bit machine. If you use Prefer 32-bit flag, CLR compiles your IL to x86 instructions, if possible (https://stackoverflow.com/a/12066861/3927447) instead of using native architecture.

When the program is running in 32-bit mode in 64-bit system, some of the system paths are virtualized. For example, the "real" system32 in the file system is redirected to SysWOW64 folder. So, when you are trying to open the file using original path to system32, you just can not find it there.

You should consider using another logic for determining location of the file to open. And, if possible, execute your code on native subsystem to skip the virtualization step.

Community
  • 1
  • 1
Nipheris
  • 487
  • 5
  • 12
  • "You should consider using another logic for determining location of the file to open." - Unfortunately, this was decided by someone else years ago and I have no other option but to look it up this way. Also, it doesn't appear to be easy to check if a file system redirect is happening. I need to find a more reliable way to deal with this, 32-bit/64-bit problems have plagued my employer for a while now. – cost Aug 19 '15 at 18:58
  • @cost Why you should choose between SysWOW64 ans system32 in your program? Why not just use Environment.SystemDirectory to get the path? And, if you uncheck Prefer 32-bit and will run on x64 system, both System32 and SysWOW64 will be available. – Nipheris Aug 19 '15 at 19:03
  • Because this file can go anywhere, and you can only be sure where it is by pulling out this string from the registry. I agree, it's a terrible idea, but out of my hands. But you did give me an idea how to fix this, or at least generate a more meaningful error – cost Aug 19 '15 at 19:05
  • You should just use native architecture for your app. There is no SysWOW64 folder on 32-bit windows, but when you are on 64-bit, and your app is 64-bit too (which is by default, if you select AnyCPU and DISABLE Prefer 32-bit), you can access both system32 and SysWOW64 and do the work. – Nipheris Aug 19 '15 at 19:30
  • @cost Of course, if SysWOW64 folder is created on 32-bit system by a mistake (for example, the bugged installer, or something), you can access this folder too, because operating system will not virtualize your paths. – Nipheris Aug 19 '15 at 19:31
  • @cost So, just don't use Prefer 32-bit :) – Nipheris Aug 19 '15 at 19:32