Opened 13 years ago

Closed 12 years ago

#2996 closed Bugs (fixed)

[iostreams] Can't open mapped_file data file for read/write access on Windows

Reported by: Allen Cronce <acronce@…> Owned by: Jonathan Turkanis
Milestone: Boost 1.39.0 Component: iostreams
Version: Boost 1.38.0 Severity: Problem
Keywords: Cc:

Description

I see access errors when trying to use mapped_file open a data file for reading and writing under Windows (built with VS2005). The same code works fine under Mac OS X, which is posix, of course.

Note that I originally found this problem under boost 1.35, but it is still present in the just released 1.39 version. Unfortunately it looks like trac has not been updated, so I cannot set the "version" to 1.38, or the "milestone" to 1.40.

Here's a code sample that works on Mac OS X and fails under Windows:

--snip--

/ Test boost iostream mapped_file. */ static int BoostMappedFileTest(void) {

int result = 0;

std::cout << "\nRunning BoostMappedFileTest..." << std::endl;

Initialize our test directory fs::path testDirPath( "BoostMappedFileTest" ); create_directory(testDirPath);

Initialize a test file buffer with some data const size_t kTestFileSize = 4096; boost::scoped_array<char> fileBuffer( new char[kTestFileSize] ); char* pCur = fileBuffer.get(); char curChar = 0; for( size_t i = 0; i < kTestFileSize; ++i ) {

*pCur++ = curChar++;

}

Write the data to a test file. Be sure to explicitly close it. fs::path testFilePath( testDirPath / "test_mapped_file" ); boost::filesystem::ofstream testFile( testFilePath, ios::trunc | ios::binary ); testFile.write(fileBuffer.get(), kTestFileSize); testFile.close();

Try and open the test file as a memory mapped file. string testFilePathStr = testFilePath.file_string(); mapped_file mappedFile(testFilePathStr);

We never get here under Windows. The file fails to open with an access error.

Compare the mapped file data to our original buffer const char* mmConstData = mappedFile.const_data(); bool compareSucceeded = (0 == memcmp(fileBuffer.get(), mmConstData, kTestFileSize)); if (!compareSucceeded) {

throw runtime_error("The boost memory mapped file data doesn't match our buffer!");

}

return result;

}

--snip--

The problem seems to come from passing GENERIC_ALL as the "dwDesiredAccess" parameter to the CreateFileA call. If I change the implementation to pass GENERIC_READ | GENERIC_WRITE, then it works in my test scenario. Please note that I haven't tried pointing the current code at an actual executable to see if it works with GENERIC_ALL.

If you assume a strict interpretation of the mapped_file API, the mode of BOOST_IOS::in would map to GENERIC_READ in the Windows world, and BOOST_IOS::out would map to GENERIC_WRITE. There is no corresponding "execute" flag that I can see in this API.

I've attached a diff created from the boost 1.39 release that fixes the problem.

My email address (in case my trac preferences doesn't work) is acronce@….

Attachments (1)

mapped_file.patch.zip (352 bytes ) - added by Allen Cronce <acronce@…> 13 years ago.
Patch file for mapped_file.cpp. Apply to the 1.39 release version to receive the patch.

Download all attachments as: .zip

Change History (3)

by Allen Cronce <acronce@…>, 13 years ago

Attachment: mapped_file.patch.zip added

Patch file for mapped_file.cpp. Apply to the 1.39 release version to receive the patch.

comment:1 by anonymous, 13 years ago

GENERIC_ALL maps to Full Control in windows... Whereas GENERIC_READ and GENERIC_WRITE map to your standard Read and Write permissions. Full control adds extra permissions for execute, plus things like Take Ownership and Change Permissions.

I cant imagine why you would need GENERIC_ALL in the case for opening the mapped file for writing. So I agree with the original poster that the reference to GENERIC_ALL should be GENERIC_READ | GENERIC_WRITE instead.

comment:2 by Steven Watanabe, 12 years ago

Resolution: fixed
Status: newclosed

(In [63035]) Replace GENERIC_ALL with GENERIC_READ | GENERIC_WRITE. Fixes #2996.

Note: See TracTickets for help on using tickets.