简体   繁体   中英

64 bit windows file opening

I'm trying to use a dialog box to open a file in my program. This works perfectly on a 32 bit system, but when I try to use it on 64 bit it is unable to open the file. I've figured out that if the file trying to be opened is in the same directory as my program, it works fine. Trying to open a file from another folder, however, doesn't work at all.

So, I tried to copy the file to the program folder. This also works fine on 32 bit but doesn't work at all on a 64 system. Any thoughts why?

char cwdl[500];
getcwd(cwdl,500);
string mystring = string(cwdl);

CFileDialog fileDlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, "All Files (*.*)|*.*||", this);
fileDlg.m_ofn.lpstrTitle = "Select New File";
if( fileDlg.DoModal() == IDOK)
{

    CString newFile= fileDlg.GetFileName();
    mystring+="\\"+newFile;
    const char * newLoc = mystring.c_str(); 
    CopyFile(newFile,newLoc,true);

this is just a snippet of the code.

UAC and file system redirection are related yet different.

User account control is a permissions based security to prevent unauthorized users from changing your file system or executing applications which may affect other users. The prompt allows you to override the security by providing administrator privileges temporarily if that was your intent.

File system redirection is to allow backwards compatibility with 32bit applications by having a mirrored 32bit system folders and registry. In fact if the action causes UAC to kick in redirection does not occur it will always try to use the 64bit version of the file in that case. Unless you specify the redirection directory explicitly or run the 32bit application with administrator privileges to bypass UAC.

Ok that said you are using a relative path so it will look for the file in the current directory for the process. If it's compiled as 32 bit process running it on systems with different architectures may not behave as expected due to aforementioned redirection.

You can use GetCurrentDirectory windows API to see what directory the current process is using and verify it is what you expected. If not you have a few options.

  • The easiest would be to use fully qualified file paths.
  • You could also have two builds one targeted for each architecture you intend to deploy on. After all if you're on a 64bit system you might as well deploy 64bit applications.
  • A more involved option would be to subclass CFileDialog and disable redirection by calling Wow64DisableWow64FsRedirection in the constructor and Wow64RevertWow64FsRedirection in the desctructor. However this is meant to be a system setting so you may get new problems by forcing your 32bit application on 64bit windows.

There are probably plenty of other options as well since there is usually many ways to skin a cat. However the first step is to put some debug code in place and verify or eliminate redirection as a culprit with GetCurrentDirectory

Maybe it's just me, but I'm seeing a strange result: in 64-bit mode, the first four bytes of the buffer used to store the location of the path, are filled with zeros.

char wk[_MAX_PATH];
char *ret = _getcwd(wk, _MAX_PATH);  // wk = "\0\0\0\0C:\\MyFolder\\..."
                                     // ret = "C:\\MyFolder\\..."

The return value OTOH is correct. "ret" points to wk + 4;

In 32-bit mode, there are no leading zeros, the path starts at the first byte. Note: this is a Multi-byte app, not Unicode.

I'm using Visual Studio 2010 (10.0.40219.1 SP1Rel).

Anyway, if you're getting the same result, that would explain why your example doesn't work. You would have to say (in 64-bit mode only):

string mystring = string(cwdl + 4);   // 64-bit only

Weird or What?

Edit: Seems to be an alignment problem. Works OK if the _getcwd is in a separate function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM