Possible Bug in the .NET Framework, Please Advise

C

Computer Guru

Hello All,

I'm at my wit's end on this one, and would appreciate any help or
insight that could be given.

Environment: Windows Vista x64 ONLY

Code:

//START BUG
string bcdedit = Environment.SystemDirectory + @"\bcdedit.exe";
Console.WriteLine(bcdedit);
if (File.Exists(bcdedit))
Console.WriteLine("bcdedit.exe found at location" + bcdedit);
else
Console.WriteLine("bcdedit.exe was not found at " + bcdedit);
//END BUG


Output:

C:\Windows\System32\bcdedit.exe
bcdedit.exe was not found at location C:\Windows\System32\bcdedit.exe



----------------------


Problem is.... I *KNOW* the file exists in C:\Windows\System32\ and
that its name is bcdedit.exe
I can see the file, I can access it, I can copy it, and I can just
about anything else that I want with it.


To me, finding files should be like duck typing:
If you can see the duck and you can copy the duck, then the duck
definitely exists.


SO

The duck exists. It's there for sure. Yet the .NET 2.0 (or is it 3.0
in Vista? I forget) Framework can't see it :/

Perhaps someone can point me in the right direction here?

This code works just fine on Vista x86.

Is this really a .NET bug?

NOTE: Attempting to access the file (without checking that it exists)
crashes the program - as is expected from the above behavior.

Desperately awaiting a sane explanation to all this.
-CG
 
J

Jon Skeet [C# MVP]

I'm at my wit's end on this one, and would appreciate any help or
insight that could be given.

Environment: Windows Vista x64 ONLY

Code:

//START BUG
string bcdedit = Environment.SystemDirectory + @"\bcdedit.exe";
Console.WriteLine(bcdedit);
if (File.Exists(bcdedit))
Console.WriteLine("bcdedit.exe found at location" + bcdedit);
else
Console.WriteLine("bcdedit.exe was not found at " + bcdedit);
//END BUG

Output:

C:\Windows\System32\bcdedit.exe
bcdedit.exe was not found at location C:\Windows\System32\bcdedit.exe

----------------------

Problem is.... I *KNOW* the file exists in C:\Windows\System32\ and
that its name is bcdedit.exe
I can see the file, I can access it, I can copy it, and I can just
about anything else that I want with it.

When you say that "you" can access it etc, do you mean from Explorer,
or from code? It could be that .NET access has been denied to system
files by default.

Jon
 
C

Computer Guru

Via explorer.

Running the program as an administrator or with UAC on/off makes no
difference.

Or are you referring to .NET Framework Policy? Why would it be any
different from non-.NET code by default?
And only on x64?

At the very least, it should return that the file /exists/ even if it
can't run it :|
 
J

Jon Skeet [C# MVP]

Via explorer.

Try copying the file in code - I suspect you'll find you can't,
possibly with a security exception.
Running the program as an administrator or with UAC on/off makes no
difference.

Or are you referring to .NET Framework Policy? Why would it be any
different from non-.NET code by default?

To provide a more secure environment under .NET without breaking
existing compatibility requirements.
And only on x64?

I seem to remember that Vista x64 has various policies which are more
restrictive than Vista x86. I wouldn't like to say I know details
though.
At the very least, it should return that the file /exists/ even if it
can't run it :|

No, if .NET says you don't have permission to look in that directory
at all, it should return false as per the documentation.

Have a look under the policy configuration and see what it says.

Jon
 
C

Computer Guru

Well, that's not good!

Many programs need access to files in system32 - at the very least
cmd.exe amongst others.

I'll have a look later though and see what it says.
 
W

Willy Denoyette [MVP]

Computer Guru said:
Hello All,

I'm at my wit's end on this one, and would appreciate any help or
insight that could be given.

Environment: Windows Vista x64 ONLY

Code:

//START BUG
string bcdedit = Environment.SystemDirectory + @"\bcdedit.exe";
Console.WriteLine(bcdedit);
if (File.Exists(bcdedit))
Console.WriteLine("bcdedit.exe found at location" + bcdedit);
else
Console.WriteLine("bcdedit.exe was not found at " + bcdedit);
//END BUG


Output:

C:\Windows\System32\bcdedit.exe
bcdedit.exe was not found at location C:\Windows\System32\bcdedit.exe



----------------------


Problem is.... I *KNOW* the file exists in C:\Windows\System32\ and
that its name is bcdedit.exe
I can see the file, I can access it, I can copy it, and I can just
about anything else that I want with it.


To me, finding files should be like duck typing:
If you can see the duck and you can copy the duck, then the duck
definitely exists.


SO

The duck exists. It's there for sure. Yet the .NET 2.0 (or is it 3.0
in Vista? I forget) Framework can't see it :/

Perhaps someone can point me in the right direction here?

This code works just fine on Vista x86.

Is this really a .NET bug?

NOTE: Attempting to access the file (without checking that it exists)
crashes the program - as is expected from the above behavior.

Desperately awaiting a sane explanation to all this.
-CG




This works if your code runs as 64bit!, so you need to make sure you have
set the platform to "X64" or "AnyCpu".

Willy.
 
W

Willy Denoyette [MVP]

Willy Denoyette said:
This works if your code runs as 64bit!, so you need to make sure you have
set the platform to "X64" or "AnyCpu".

Willy.



I suppose I should expand a bit on this, the reason that your code fails is
a result of what is called " Syswow64 redirection".
"%Systemroot%\System32" is reserved for 64 bit applications, the File System
redirects all accesses from 32 bit applications to "%Systemroot%\SysWOW64"
and as this directory does not include bcdedit.exe, your code fails to find
the executable file.

One option to solve this is to compile the program as 64bit or MSIL, another
is to bypass the FS redirection by using "%Systemroot%Sysnative" whenever
you need to access the native System32 directory.
Your sample code will work as expected when you change this line:
string bcdedit = Environment.SystemDirectory + @"\bcdedit.exe";

into:
string bcdedit =
Environment.ExpandEnvironmentVariables(@"%systemroot%\Sysnative") +
@"\bcdedit.exe";

Willy.
 
G

Guest

There is similar redirection with registry keys under HKLM. This drove me
crazy one afternoon.
 
W

Willy Denoyette [MVP]

True, similar but not exactly the same. The "File" and "Registry"
"redirection" is what is officially called "Virtualization", this is for
backward compatibility purposes only, and can (should) be turned off by
inserting a manifest into the executable file. The System32 redirection
however, is not turned of by a manifest. The "Virtualization" is a temporary
feature, supposed to be removed in the (IMO not so near) future, while the
System32 redirection is here to stay as long as we will have 32 bit
applications running on Windows.

Willy.
 
C

Computer Guru

I suppose I should expand a bit on this, the reason that your code fails is
a result of what is called " Syswow64 redirection".
"%Systemroot%\System32" is reserved for 64 bit applications, the File System
redirects all accesses from 32 bit applications to "%Systemroot%\SysWOW64"
and as this directory does not includebcdedit.exe, your code fails to find
the executable file.

One option to solve this is to compile the program as 64bit or MSIL, another
is to bypass the FS redirection by using "%Systemroot%Sysnative" whenever
you need to access the native System32 directory.
Your sample code will work as expected when you change this line:
string bcdedit = Environment.SystemDirectory + @"\bcdedit.exe";

into:
string bcdedit =
Environment.ExpandEnvironmentVariables(@"%systemroot%\Sysnative") +
@"\bcdedit.exe";

Willy.

This won't work on x86 machines though, will it?

So I guess I'll have to implement a check for x86 or x64 then use the
appropriate one?

Thanks for clearing it up though, it drove me crazy and I couldn't
find ANY explanation on Technet/MSDN.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top