1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
/*
* This file is part of rsyncrypto - rsync friendly encryption
* Copyright (C) 2005 Shachar Shemesh for Lingnu Open Source Consulting (http://www.lignu.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Win32 portable implementation
#if !defined(_WIN32)
#error Win32 only header included from non-Win32 build environment
#endif
#ifndef _AUTOMMAP_H
#define _AUTOMMAP_H
#include <errno.h>
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
// automap will auto-release mmaped areas
class autommap {
HANDLE mapping;
void *ptr;
size_t size;
// Disable default copy constructor
autommap( const autommap & );
void mapfile(void *start, size_t length, int prot, int flags, file_t fd, off_t offset)
{
DWORD flProtect;
DWORD dwDesiredAccess;
ptr=NULL;
mapping=NULL;
switch( prot ) {
case PROT_WRITE|PROT_READ:
flProtect=PAGE_READWRITE;
dwDesiredAccess=FILE_MAP_WRITE;
break;
case PROT_READ:
flProtect=PAGE_READONLY;
dwDesiredAccess=FILE_MAP_READ;
break;
default:
#if defined(EXCEPT_CLASS)
throw EXCEPT_CLASS("Unsupported mmap protection mode");
#else
return;
#endif
}
if( length==0 ) {
DWORD highsize;
length=GetFileSize( fd, &highsize );
if( highsize!=0 )
throw EXCEPT_CLASS("File too big to be mapped", ERROR_NOT_ENOUGH_MEMORY );
}
// If the actual file length is 0, do not map
if( length!=0 ) {
mapping=CreateFileMapping( fd, NULL, flProtect, 0, 0, NULL );
if( mapping==NULL )
throw EXCEPT_CLASS("CreateFileMapping failed", GetLastError() );
ptr=MapViewOfFileEx( mapping, dwDesiredAccess, static_cast<DWORD>(offset>>32),
static_cast<DWORD>(offset), length, start );
if( ptr==NULL ) {
CloseHandle( mapping );
mapping=NULL;
#if defined(EXCEPT_CLASS)
throw EXCEPT_CLASS("mmap failed", errno);
#endif
}
}
size=length;
}
public:
autommap() : ptr(NULL), mapping(NULL), size(0)
{
}
autommap(void *start, size_t length, int prot, int flags, file_t fd, off_t offset ) :
mapping(NULL), ptr(NULL), size(0)
{
mapfile(start, length, prot, flags, fd, offset);
}
// Map an entire file into memory
autommap(file_t fd, int prot) : mapping(NULL), ptr(NULL), size(0)
{
mapfile(NULL, 0, prot, 0, fd, 0);
}
~autommap()
{
clear();
}
void *get() const
{
return ptr;
}
unsigned char *get_uc() const
{
return static_cast<unsigned char *>(ptr);
}
autommap &operator=( autommap &that )
{
clear();
ptr=that.ptr;
mapping=that.mapping;
that.ptr=NULL;
that.mapping=NULL;
return *this;
}
void clear()
{
if( ptr!=NULL ) {
UnmapViewOfFile(ptr);
ptr=NULL;
CloseHandle(mapping);
}
ptr=NULL;
mapping=NULL;
}
size_t getsize() const {
return size;
}
};
#endif // _AUTOMMAP_H
|