none
64 bit XP and system32 folder

    Question

  • This Code fails on XP 64 bit even if the file exists in the target folder

    The exe is 32 bit

     

    CString str;
     

    str = "C:\\WINDOWS\\system32\\drivers\\acpi.sys";

    if(!PathFileExists(str))

    {
             //Fails but the file exists and can be seen in explorer

    }

     

    i can paste any file in that folder (text file or whatever)  and the result will be file not found (errcode=2)

     

    it shows same behaviour in "c:\windows\system32" folder

     

    So is there some security issue i am not seeing cause this thing runs fine in vista with UAC enabled

     

    Thanks

     

    Thursday, May 31, 2007 1:07 PM

Answers

  • It is most likely because of file system redirection. Since your's is a 32 bit app from which the code executes, any access to c:\Windows\system32 will be silently redirected to c:\windows\syswow64 folder. The sysWow64 folder is THE place for 32bit components. This was done so that legacy apps that aren't aware of 64bit can continue to run seamlessly using the 32-bit components.

     

    In your case, before you execute a call to PathFileExists, you have to turn off redirection ( if it was ON ), execute the call , and then turn back redirection on ( if it was ON to start with ).

     

    Please read this informative article and it has sample code for turning on and off redirection.

    http://www.64advantage.com/files/64-bit%20Insider%20Volume%201%20Issue%205.pdf

    Also, as a suggestion, if you are targeting different flavors of OSes, the APIs used may not be supported. Use LoadLibrary and GetProcAddress instead like below:

     

    Code Snippet

    typedef BOOL (WINAPI *LPFN_Wow64DisableWow64FsRedirection)(PVOID* OldValue);
    typedef BOOL (WINAPI *LPFN_Wow64RevertWow64FsRedirection)(PVOID OldValue);

     

    //turn off File System Redirection first
      PVOID OldValue;
      
      LPFN_Wow64DisableWow64FsRedirection pfnWow64DisableWowFsRedirection = (LPFN_Wow64DisableWow64FsRedirection)GetProcAddress(GetModuleHandle(_T("kernel32")),"Wow64DisableWow64FsRedirection");
      LPFN_Wow64RevertWow64FsRedirection pfnWow64RevertWow64FsRedirection = (LPFN_Wow64RevertWow64FsRedirection)GetProcAddress(GetModuleHandle(_T("kernel32")),"Wow64RevertWow64FsRedirection");
      if (pfnWow64DisableWowFsRedirection && pfnWow64RevertWow64FsRedirection)
      {
       if(TRUE == pfnWow64DisableWowFsRedirection(&OldValue))
       {
         //do your stuff.

     

       //turn it back on

        pfnWow64RevertWow64FsRedirection(OldValue);
       }
      }

     

    Friday, June 01, 2007 12:23 AM

All replies

  • It is most likely because of file system redirection. Since your's is a 32 bit app from which the code executes, any access to c:\Windows\system32 will be silently redirected to c:\windows\syswow64 folder. The sysWow64 folder is THE place for 32bit components. This was done so that legacy apps that aren't aware of 64bit can continue to run seamlessly using the 32-bit components.

     

    In your case, before you execute a call to PathFileExists, you have to turn off redirection ( if it was ON ), execute the call , and then turn back redirection on ( if it was ON to start with ).

     

    Please read this informative article and it has sample code for turning on and off redirection.

    http://www.64advantage.com/files/64-bit%20Insider%20Volume%201%20Issue%205.pdf

    Also, as a suggestion, if you are targeting different flavors of OSes, the APIs used may not be supported. Use LoadLibrary and GetProcAddress instead like below:

     

    Code Snippet

    typedef BOOL (WINAPI *LPFN_Wow64DisableWow64FsRedirection)(PVOID* OldValue);
    typedef BOOL (WINAPI *LPFN_Wow64RevertWow64FsRedirection)(PVOID OldValue);

     

    //turn off File System Redirection first
      PVOID OldValue;
      
      LPFN_Wow64DisableWow64FsRedirection pfnWow64DisableWowFsRedirection = (LPFN_Wow64DisableWow64FsRedirection)GetProcAddress(GetModuleHandle(_T("kernel32")),"Wow64DisableWow64FsRedirection");
      LPFN_Wow64RevertWow64FsRedirection pfnWow64RevertWow64FsRedirection = (LPFN_Wow64RevertWow64FsRedirection)GetProcAddress(GetModuleHandle(_T("kernel32")),"Wow64RevertWow64FsRedirection");
      if (pfnWow64DisableWowFsRedirection && pfnWow64RevertWow64FsRedirection)
      {
       if(TRUE == pfnWow64DisableWowFsRedirection(&OldValue))
       {
         //do your stuff.

     

       //turn it back on

        pfnWow64RevertWow64FsRedirection(OldValue);
       }
      }

     

    Friday, June 01, 2007 12:23 AM
  • The file system redirection as well as the registry redirection is on by default. So you have to go through the above process to turn it off.

    There are two things to remember when doing things in the system32 directory though. First of all, all components in the x64 build system32 are 64 bit components and you can't do much to them because you can't load 64 bit files into a 32 bit process without thunking or by using COM.

    The second is don't just put random stuff into the system32 directory. This is true of all versions of Windows, even more so with x64. First of all 32 bit apps will fail to find them. Secondly you can disrupt a 64 bit app because it tries to load something which is 32 bit.

    A final note since I saw you was trying to access the drivers directory. You must remember that 64 bit windows must use 64 bit drivers. Any 32 bit drivers will just fail to load.

    Friday, June 01, 2007 2:15 AM
  • Thanks a lot for such great answer, i suspected it was because its a 32 bit app how do you make a 64 bit app using VS2005
    Friday, June 01, 2007 2:52 AM
  • If you are using the Express edition then you can't directly do it. You will need to use the compiler from the Windows SDK.

    If you are using VS2005 standard or better then first of all you must have installed the x64 compiler. You can verify this by checking that vc\bin\x86_amd64 and\or amd64 (if you are using the x64 version of windows) is present.

    You then go to Build->Configuration Manager in Active Solution Platform select <new...> and in the window that pops up select x64 in the top drop down box. You should then be able to build for x64.

    You can then change between builds by using the Solution Platform on the standard toolbar (the one which initially says Win32) or through configuration manager.

    Friday, June 01, 2007 3:15 AM
  • crescens2k brings up good points. It would be interesting to know what exactly you are trying to do with the system32 folders ?

     

    If it is just a  matter of checking if a file exists ( in this case it appears they are driver files ), you could as well use a 32-bit app. This is preferred to having 2 seperate builds , one for 32-bit and one for 64-bit and related maintainece issues. This is valid as long as your application is targeted for 32/64 bit systems.

     

     

    Friday, June 01, 2007 4:21 PM