Elisha Berns wrote:
Christian,
I don't have any simple snippet that I can send because I'm mapping files that are provided by XercesC as System Ids for whatever xml schema I open. The whole thing is too involved to just paste into a short email because it entails loading the schema into Xerces, getting all available System Ids for the namespaces present and then finally mapping those System Ids (provided they are local files). These files may/may not be locked by Xerces when I attempt to map them, I simply don't know. That said, my first observation is with the flag I use: FILE_ATTRIBUTE_READONLY in the call to CreateFile(...) which is not used in mapped_file_source::open_impl.
But I will be glad to test any changes proposed since I can just
Jonathan, Thanks for the reply. I have found a fix for this problem. It consists of two things: 1) A small code change in mapped_file.cpp to make extra sure the correct flag is set: //--------------Open underlying file------------------------------------ pimpl_->handle_ = ::CreateFileA( p.path.c_str(), readonly ? GENERIC_READ : GENERIC_ALL, FILE_SHARE_READ, NULL, (p.new_file_size != 0 && !readonly) ? CREATE_ALWAYS : OPEN_EXISTING, readonly ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_TEMPORARY, NULL ); if (pimpl_->handle_ == INVALID_HANDLE_VALUE) detail::cleanup_and_throw(*pimpl_, "failed opening file"); it's the line: readonly ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_TEMPORARY, 2) My apologies about this second thing, since it's my problem, even if it is an issue of checking under the hood what assumptions are made by Boost.Iostreams. The issue is that the file names that I get from XercesC contain a mix of forward slashes and back slashes for directory separators. In Win32, the file mapping API CreateFileMapping doesn't accept back slashes except in a few cases. So the assumption being used in Boost.Iostreams that the file mapping object can be named with the same path name that opens the file (see p.path.c_str()), doesn't always hold true because a valid path for CreateFile is not always a valid object name for CreateFileMapping. Create mapping------------------------------------------ try_again: // Target of goto in following section. pimpl_->mapped_handle_ = ::CreateFileMappingA( pimpl_->handle_, NULL, readonly ? PAGE_READONLY : PAGE_READWRITE, 0, 0, readonly ? 0 : p.path.c_str() ); if (pimpl_->mapped_handle_ == NULL) { detail::cleanup_and_throw(*pimpl_, "couldn't create mapping"); } It may be wise to rethink the assumption that open_impl makes regarding this matter, and if not fix up the path name to convert back slashes to forward slashes (as I need to do) then perhaps minimally throw a specific exception for a bad object name since the problem is rather obscure. As for the original message, here it is again. And I apologize about its tone since I was a wee bit cranky yesterday dealing with it all. At this juncture I would like to commend all the boost contributors for their overall brilliance, esprit de corps about the boost project(s) and mention that every other day I just sit back and say, "Wow, I can't believe what's being created". Anyways, here's my lame message: Hi again, Odd, today I have only had PROBLEMS with boost. I guess it's just one of those days. Anyways, the open_impl() method for iostreams::mapped_file_source just doesn't open any mappings for files. I realize that it is reused by the mapped_file class, but that is what seems to cloud the design, flow and working of it as it needs to please everyone here, and it doesn't. It always throws in this location: pimpl_->mapped_handle_ = ::CreateFileMappingA( pimpl_->handle_, NULL, readonly ? PAGE_READONLY : PAGE_READWRITE, 0, 0, p.path.c_str() ); if (pimpl_->mapped_handle_ == NULL) { detail::cleanup_and_throw(*pimpl_, "couldn't create mapping"); } However, if I use just the raw Win32 APIs all works fine: HANDLE hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if ( hFile == INVALID_HANDLE_VALUE ) return; HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if ( hFileMapping == 0 ) { CloseHandle(hFile); return; } void* pView = ::MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); if ( pView == 0 ) { CloseHandle(hFileMapping); CloseHandle(hFile); return; } Anyways, here my desire is to use the boost libraries as an insulation layer to enable writing cross-platform C++, but obviously if it doesn't work that idea doesn't go too far. So I really hope this gets addressed. Many thanks, Elisha plug
it into my own mess.
Elisha
I can't find your original message. Can you report it?
Jonathan
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users