Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2008 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): Andrea Weikert. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #if defined(WIN32) 00034 00035 #include <windows.h> 00036 #include <errno.h> 00037 #include <io.h> 00038 #include <sys/types.h> 00039 #include <stdio.h> 00040 00041 #include "mmap_win.h" 00042 00043 #ifndef FILE_MAP_EXECUTE 00044 //not defined in earlier versions of the Platform SDK (before February 2003) 00045 #define FILE_MAP_EXECUTE 0x0020 00046 #endif 00047 00048 /* copied from BKE_utildefines.h ugh */ 00049 #ifdef __GNUC__ 00050 # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) 00051 #else 00052 # define UNUSED(x) x 00053 #endif 00054 00055 /* --------------------------------------------------------------------- */ 00056 /* local storage definitions */ 00057 /* --------------------------------------------------------------------- */ 00058 /* all memory mapped chunks are put in linked lists */ 00059 typedef struct mmapLink 00060 { 00061 struct mmapLink *next,*prev; 00062 } mmapLink; 00063 00064 typedef struct mmapListBase 00065 { 00066 void *first, *last; 00067 } mmapListBase; 00068 00069 typedef struct MemMap { 00070 struct MemMap *next,*prev; 00071 void *mmap; 00072 HANDLE fhandle; 00073 HANDLE maphandle; 00074 } MemMap; 00075 00076 /* --------------------------------------------------------------------- */ 00077 /* local functions */ 00078 /* --------------------------------------------------------------------- */ 00079 00080 static void mmap_addtail(volatile mmapListBase *listbase, void *vlink); 00081 static void mmap_remlink(volatile mmapListBase *listbase, void *vlink); 00082 static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr); 00083 00084 static int mmap_get_prot_flags (int flags); 00085 static int mmap_get_access_flags (int flags); 00086 00087 /* --------------------------------------------------------------------- */ 00088 /* vars */ 00089 /* --------------------------------------------------------------------- */ 00090 volatile static struct mmapListBase _mmapbase; 00091 volatile static struct mmapListBase *mmapbase = &_mmapbase; 00092 00093 00094 /* --------------------------------------------------------------------- */ 00095 /* implementation */ 00096 /* --------------------------------------------------------------------- */ 00097 00098 /* mmap for windows */ 00099 void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t offset) 00100 { 00101 HANDLE fhandle = INVALID_HANDLE_VALUE; 00102 HANDLE maphandle; 00103 int prot_flags = mmap_get_prot_flags(prot); 00104 int access_flags = mmap_get_access_flags(prot); 00105 MemMap *mm = NULL; 00106 void *ptr = NULL; 00107 00108 if ( flags & MAP_FIXED ) { 00109 return MAP_FAILED; 00110 } 00111 00112 /* 00113 if ( fd == -1 ) { 00114 _set_errno( EBADF ); 00115 return MAP_FAILED; 00116 } 00117 */ 00118 00119 if ( fd != -1 ) { 00120 fhandle = (HANDLE) _get_osfhandle (fd); 00121 } 00122 if ( fhandle == INVALID_HANDLE_VALUE ) { 00123 if (!(flags & MAP_ANONYMOUS)) { 00124 errno = EBADF; 00125 return MAP_FAILED; 00126 } 00127 } else { 00128 if ( !DuplicateHandle( GetCurrentProcess(), fhandle, GetCurrentProcess(), 00129 &fhandle, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { 00130 return MAP_FAILED; 00131 } 00132 } 00133 00134 maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL); 00135 if ( maphandle == 0 ) { 00136 errno = EBADF; 00137 return MAP_FAILED; 00138 } 00139 00140 ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0); 00141 if ( ptr == NULL ) { 00142 DWORD dwLastErr = GetLastError(); 00143 if ( dwLastErr == ERROR_MAPPED_ALIGNMENT ) 00144 errno=EINVAL; 00145 else 00146 errno=EACCES; 00147 CloseHandle(maphandle); 00148 return MAP_FAILED; 00149 } 00150 00151 mm= (MemMap *)malloc(sizeof(MemMap)); 00152 if (!mm) { 00153 errno=ENOMEM; 00154 } 00155 mm->fhandle = fhandle; 00156 mm->maphandle = maphandle; 00157 mm->mmap = ptr; 00158 mmap_addtail(mmapbase, mm); 00159 00160 return ptr; 00161 } 00162 00163 /* munmap for windows */ 00164 intptr_t munmap(void *ptr, intptr_t UNUSED(size)) 00165 { 00166 MemMap *mm = mmap_findlink(mmapbase, ptr); 00167 if (!mm) { 00168 errno=EINVAL; 00169 return -1; 00170 } 00171 UnmapViewOfFile( mm->mmap ); 00172 CloseHandle( mm->maphandle ); 00173 CloseHandle( mm->fhandle); 00174 mmap_remlink(mmapbase, mm); 00175 free(mm); 00176 return 0; 00177 } 00178 00179 /* --------------------------------------------------------------------- */ 00180 /* local functions */ 00181 /* --------------------------------------------------------------------- */ 00182 00183 static void mmap_addtail(volatile mmapListBase *listbase, void *vlink) 00184 { 00185 struct mmapLink *link= vlink; 00186 00187 if (link == 0) return; 00188 if (listbase == 0) return; 00189 00190 link->next = 0; 00191 link->prev = listbase->last; 00192 00193 if (listbase->last) ((struct mmapLink *)listbase->last)->next = link; 00194 if (listbase->first == 0) listbase->first = link; 00195 listbase->last = link; 00196 } 00197 00198 static void mmap_remlink(volatile mmapListBase *listbase, void *vlink) 00199 { 00200 struct mmapLink *link= vlink; 00201 00202 if (link == 0) return; 00203 if (listbase == 0) return; 00204 00205 if (link->next) link->next->prev = link->prev; 00206 if (link->prev) link->prev->next = link->next; 00207 00208 if (listbase->last == link) listbase->last = link->prev; 00209 if (listbase->first == link) listbase->first = link->next; 00210 } 00211 00212 static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr) 00213 { 00214 MemMap *mm; 00215 00216 if (ptr == 0) return NULL; 00217 if (listbase == 0) return NULL; 00218 00219 mm = (MemMap *)listbase->first; 00220 while (mm) { 00221 if (mm->mmap == ptr) { 00222 return mm; 00223 } 00224 mm = mm->next; 00225 } 00226 return NULL; 00227 } 00228 00229 static int mmap_get_prot_flags (int flags) 00230 { 00231 int prot = PAGE_NOACCESS; 00232 00233 if ( ( flags & PROT_READ ) == PROT_READ ) { 00234 if ( ( flags & PROT_WRITE ) == PROT_WRITE ) { 00235 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 00236 } else { 00237 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY; 00238 } 00239 } else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) { 00240 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY; 00241 } else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) { 00242 prot = PAGE_EXECUTE_READ; 00243 } 00244 return prot; 00245 } 00246 00247 static int mmap_get_access_flags (int flags) 00248 { 00249 int access = 0; 00250 00251 if ( ( flags & PROT_READ ) == PROT_READ ) { 00252 if ( ( flags & PROT_WRITE ) == PROT_WRITE ) { 00253 access = FILE_MAP_WRITE; 00254 } else { 00255 access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ; 00256 } 00257 } else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) { 00258 access = FILE_MAP_COPY; 00259 } else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) { 00260 access = FILE_MAP_EXECUTE; 00261 } 00262 return access; 00263 } 00264 00265 00266 #endif // WIN32 00267 00268 00269 00270 00271