Boost logo

Boost Users :

From: Elisha Berns (e.berns_at_[hidden])
Date: 2005-08-26 16:10:32


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

> 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
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_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net