void* MemoryMappedFile::remapPrivateView(void *oldPrivateAddr) { verify( Lock::isW() ); LockMongoFilesExclusive lockMongoFiles; RemapLock lk; // Interlock with PortMessageServer::acceptedMP() to stop thread creation clearWritableBits(oldPrivateAddr); if( !UnmapViewOfFile(oldPrivateAddr) ) { DWORD dosError = GetLastError(); log() << "UnMapViewOfFile for " << filename() << " failed with error " << errnoWithDescription( dosError ) << " in MemoryMappedFile::remapPrivateView" << endl; fassertFailed( 16168 ); } void* newPrivateView = MapViewOfFileEx( maphandle, // file mapping handle FILE_MAP_READ, // access 0, 0, // file offset, high and low 0, // bytes to map, 0 == all oldPrivateAddr ); // we want the same address we had before if ( 0 == newPrivateView ) { DWORD dosError = GetLastError(); log() << "MapViewOfFileEx for " << filename() << " failed with error " << errnoWithDescription( dosError ) << " (file size is " << len << ")" << " in MemoryMappedFile::remapPrivateView" << endl; } fassert( 16148, newPrivateView == oldPrivateAddr ); return newPrivateView; }
LPVOID DL_MapViewOfFileExNuma(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress, DWORD nndPreferred) { typedef LPVOID (WINAPI * MapViewOfFileExNuma_t)(HANDLE, DWORD, DWORD, DWORD, SIZE_T, LPVOID, DWORD); static auto fcn = (MapViewOfFileExNuma_t)GetKernelProcAddress("MapViewOfFileExNuma"); if (not fcn) return MapViewOfFileEx(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress); return fcn(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress, nndPreferred); }
bool CreateBitmap(HDC dc, size_t width, size_t height, HBITMAP& hBitmap, void** pBitmapData, void* memory) { BITMAPINFO bitmapInfo; bitmapInfo.bmiHeader.biBitCount = 32; bitmapInfo.bmiHeader.biClrImportant = 0; bitmapInfo.bmiHeader.biClrUsed = 0; bitmapInfo.bmiHeader.biCompression = BI_RGB; bitmapInfo.bmiHeader.biHeight = -height; bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO); bitmapInfo.bmiHeader.biWidth = width; bitmapInfo.bmiHeader.biSizeImage = 0; bitmapInfo.bmiHeader.biXPelsPerMeter = 0; bitmapInfo.bmiHeader.biYPelsPerMeter = 0; if(memory != NULL) { HDC memoryDC = CreateCompatibleDC(dc); if(memoryDC == NULL) return false; HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, width*height*4, NULL); MapViewOfFileEx(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0, memory); hBitmap = CreateDIBSection(memoryDC, &bitmapInfo, DIB_RGB_COLORS, pBitmapData, hMapping, 0); } else hBitmap = CreateDIBSection(dc, &bitmapInfo, DIB_RGB_COLORS, pBitmapData, NULL, 0); return (hBitmap != 0); }
/* mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); */ void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { HANDLE h; void *data; (void) offset; if ((flags != MAP_SHARED) || (prot != PROT_READ)) { /* Not supported in this port */ return MAP_FAILED; }; h = CreateFileMapping((HANDLE) FDAPI_get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL); if (!h) { return MAP_FAILED; } data = MapViewOfFileEx(h, FILE_MAP_READ, 0, 0, length, start); CloseHandle(h); if (!data) { return MAP_FAILED; } return data; }
/* In order to create a new message queue, or access an existing queue, the shmget() system call is used. SYSTEM CALL: shmget(); PROTOTYPE: int shmget ( key_t key, int size, int shmflg ); RETURNS: shared memory segment identifier on success -1 on error: errno = EINVAL (Invalid segment size specified) EEXIST (Segment exists, cannot create) EIDRM (Segment is marked for deletion, or was removed) ENOENT (Segment does not exist) EACCES (Permission denied) ENOMEM (Not enough memory to create segment) NOTES: This particular call should almost seem like old news at this point. It is strikingly similar to the corresponding get calls for message queues and semaphore sets. The first argument to shmget() is the key value (in our case returned by a call to ftok()). This key value is then compared to existing key values that exist within the kernel for other shared memory segments. At that point, the open or access operation is dependent upon the contents of the shmflg argument. IPC_CREAT Create the segment if it doesn't already exist in the kernel. IPC_EXCL When used with IPC_CREAT, fail if segment already exists. If IPC_CREAT is used alone, shmget() either returns the segment identifier for a newly created segment, or returns the identifier for a segment which exists with the same key value. If IPC_EXCL is used along with IPC_CREAT, then either a new segment is created, or if the segment exists, the call fails with -1. IPC_EXCL is useless by itself, but when combined with IPC_CREAT, it can be used as a facility to guarantee that no existing segment is opened for access. Once again, an optional octal mode may be OR'd into the mask. Let's create a wrapper function for locating or creating a shared memory segment : int open_segment( key_t keyval, int segsize ) { int shmid; if((shmid = shmget( keyval, segsize, IPC_CREAT | 0660 )) == -1) { return(-1); } return(shmid); } Note the use of the explicit permissions of 0660. This small function either returns a shared memory segment identifier (int), or -1 on error. The key value and requested segment size (in bytes) are passed as arguments. Once a process has a valid IPC identifier for a given segment, the next step is for the process to attach or map the segment into its own addressing space. */ TSRM_API int shmget ( key_t key, int size, int shmflg ) { //int shmget(int key, int size, int flags) { shm_pair *shm; char shm_segment[26], shm_info[29]; HANDLE shm_handle, info_handle; BOOL created = FALSE; DWORD errnum; //for DEBUG if (size < 0) { return -1; } sprintf(shm_segment, "TSRM_SHM_SEGMENT:%d", key); sprintf(shm_info, "TSRM_SHM_DESCRIPTOR:%d", key); shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment); info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info); if ((!shm_handle && !info_handle)) { if (shmflg & IPC_CREAT) { shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment); info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info); created = TRUE; } if ((!shm_handle || !info_handle)) { errnum = GetLastError(); return -1; } } else { if (shmflg & IPC_EXCL) { return -1; } } if ((shm = shm_get(CREATE_NEW_IF_NOT_EXISTS, key, NULL)) == NULL) return -1; shm->segment = shm_handle; shm->info = info_handle; shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL); if (created) { shm->descriptor->shm_perm.key = key; shm->descriptor->shm_segsz = size; shm->descriptor->shm_ctime = time(NULL); shm->descriptor->shm_cpid = getpid(); shm->descriptor->shm_perm.mode = shmflg; shm->descriptor->shm_perm.cuid = shm->descriptor->shm_perm.cgid= 0; shm->descriptor->shm_perm.gid = shm->descriptor->shm_perm.uid = 0; shm->descriptor->shm_atime = shm->descriptor->shm_dtime = 0; shm->descriptor->shm_lpid = shm->descriptor->shm_nattch = 0; shm->descriptor->shm_perm.mode = shm->descriptor->shm_perm.seq = 0; } if (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz ) { CloseHandle(shm->segment); UnmapViewOfFile(shm->descriptor); CloseHandle(shm->info); return -1; } return key; }
void* MemArena::CreateViewAt(s64 offset, size_t size, void* base) { #ifdef _WIN32 return MapViewOfFileEx(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size, base); #else return mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, offset); #endif }
/* A template function which creates/attaches shm seg handle * to the shared memory. Used by user-exposed functions below */ static inline int MPL_shm_seg_create_attach_templ(MPL_shm_hnd_t hnd, intptr_t seg_sz, void **shm_addr_ptr, int offset, int flag) { HANDLE lhnd = INVALID_HANDLE_VALUE; int rc = MPL_SHM_SUCCESS; ULARGE_INTEGER seg_sz_large; seg_sz_large.QuadPart = seg_sz; if (!MPLI_shm_ghnd_is_valid(hnd)) { rc = MPLI_shm_ghnd_set_uniq(hnd); if (rc) { goto fn_exit; } } if (flag & MPLI_SHM_FLAG_SHM_CREATE) { lhnd = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, seg_sz_large.HighPart, seg_sz_large.LowPart, MPLI_shm_ghnd_get_by_ref(hnd)); if (lhnd == NULL) { rc = MPL_SHM_EINTERN; goto fn_exit; } MPLI_shm_lhnd_set(hnd, lhnd); } else { if (!MPLI_shm_lhnd_is_valid(hnd)) { /* Strangely OpenFileMapping() returns NULL on error! */ lhnd = OpenFileMapping(FILE_MAP_WRITE, FALSE, MPLI_shm_ghnd_get_by_ref(hnd)); if (lhnd == NULL) { rc = MPL_SHM_EINTERN; goto fn_exit; } MPLI_shm_lhnd_set(hnd, lhnd); } } if (flag & MPLI_SHM_FLAG_SHM_ATTACH) { if (flag & MPLI_SHM_FLAG_FIXED_ADDR) { void *start_addr = (void *) *shm_addr_ptr; /* The start_addr must be a multiple of the system's memory allocation granularity, * or the function fails. To determine the memory allocation granularity of the system, * use the GetSystemInfo function. If there is not enough address space at the * specified address, the function fails. * If the function fails, the return value is NULL.*/ *shm_addr_ptr = MapViewOfFileEx(MPLI_shm_lhnd_get(hnd), FILE_MAP_WRITE, 0, offset, 0, start_addr); } else { *shm_addr_ptr = MapViewOfFile(MPLI_shm_lhnd_get(hnd), FILE_MAP_WRITE, 0, offset, 0); } if (*shm_addr_ptr == NULL) { rc = MPL_SHM_EINVAL; } } fn_exit: return rc; }
APIRET os2APIENTRY DosGetSharedMem(PVOID pb, ULONG flag) { if(!pb) return 487; //error_invalid_address if(flag&(PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD)!=flag) return 87; //error_invalid_parameter PoolLock pl; SM_Pool *ppool=lockPool(&pl); for(int i=0; i<MAXSHAREDMEMOBJECTS; i++) if(ppool->SM_Object[i].SM_ReferenceCount && ppool->SM_Object[i].SM_BaseAddress==(DWORD)pb) break; if(i>=MAXSHAREDMEMOBJECTS) { unlockPool(&pl); return 487; //error_invalid_address } if(hFileMapping[i]!=NULL) { //already mapped unlockPool(&pl); return 0; } //open file mapping hFileMapping[i] = OpenFileMapping(flag&PAG_WRITE?FILE_MAP_WRITE:FILE_MAP_READ, FALSE, ppool->SM_Object[i].SM_Filemapname ); if(hFileMapping[i]==NULL) { unlockPool(&pl); return 8; //error_not_enough_memory } //map unreserveObjectAddresses(i); LPVOID lpv = MapViewOfFileEx(hFileMapping[i], flag&PAG_WRITE ? FILE_MAP_WRITE:FILE_MAP_READ, 0,0, (DWORD)ppool->SM_Object[i].SM_Size, (LPVOID)ppool->SM_Object[i].SM_BaseAddress ); if((DWORD)lpv!=ppool->SM_Object[i].SM_BaseAddress) { //nt didn't like it reserveObjectAddresses(i); CloseHandle(hFileMapping[i]); hFileMapping[i]=NULL; return 8; //error_not_enough_memory } unlockPool(&pl); return 0; }
void* MemoryMappedFile::remapPrivateView(void *oldPrivateAddr) { bool ok = UnmapViewOfFile(oldPrivateAddr); assert(ok); // we want the new address to be the same as the old address in case things keep pointers around (as namespaceindex does). void *p = MapViewOfFileEx(maphandle, FILE_MAP_COPY, 0, 0, /*dwNumberOfBytesToMap 0 means to eof*/0 /*len*/, oldPrivateAddr); assert(p); assert(p == oldPrivateAddr); return p; }
void *shmat(int shmid, LPVOID shmaddr, int shmflg) { struct shmid_ds *shm = &shmids[shmid]; if(shm->addr == shmaddr ) return shm->addr; shm->addr = MapViewOfFileEx (shm->filemapping, FILE_MAP_WRITE, 0, 0, shm->size, shmaddr); if (addr == NULL) win32_error("MapViewOfFileEx %08X", shmaddr); write_log ("shmat %08X -> %08X\n", shmaddr, shm->addr); shm->attached = 1; return shm->addr; }
void * mmap( void *desired_addr, size_t len, int mmap_prot, int mmap_flags, HANDLE fd, size_t off ) { HANDLE fmh; void *base_addr; SECURITY_ATTRIBUTES sa; DWORD prot; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; prot = 0; if (mmap_prot & PROT_WRITE){ if (mmap_flags & MAP_PRIVATE){ prot = PAGE_WRITECOPY; } else { prot = PAGE_READWRITE; } } else if (mmap_prot & PROT_READ){ prot = PAGE_READONLY; } if (mmap_prot & PROT_EXEC){ prot |= SEC_IMAGE; } if (mmap_flags & MAP_NORESERVE){ prot |= SEC_NOCACHE; } /* MAP_FIXED is unhandled */ fmh = CreateFileMapping(fd, &sa, prot, 0, len, NULL); if (fmh == NULL){ return NULL; } prot = 0; if (mmap_prot & PROT_WRITE){ if (mmap_flags & MAP_PRIVATE){ prot |= FILE_MAP_COPY; } else { prot |= FILE_MAP_WRITE; } } if (mmap_prot & PROT_READ){ prot |= FILE_MAP_READ; } if (mmap_prot & PROT_EXEC && mmap_flags & MAP_PRIVATE){ prot |= FILE_MAP_COPY; } base_addr = MapViewOfFileEx(fmh, prot, 0, off, len, desired_addr); /* I hope that Windows keeps its own copy */ CloseHandle(fmh); return base_addr; }
BOOL My_MapViewOfFileEx() { HANDLE hFileMappingObject=NULL; DWORD dwDesiredAccess=NULL; DWORD dwFileOffsetHigh=NULL; DWORD dwFileOffsetLow=NULL; SIZE_T dwNumberOfBytesToMap=NULL; LPVOID lpBaseAddress=NULL; LPVOID returnVal_Real = NULL; LPVOID returnVal_Intercepted = NULL; DWORD error_Real = 0; DWORD error_Intercepted = 0; __try{ disableInterception(); returnVal_Real = MapViewOfFileEx (hFileMappingObject,dwDesiredAccess,dwFileOffsetHigh,dwFileOffsetLow,dwNumberOfBytesToMap,lpBaseAddress); error_Real = GetLastError(); enableInterception(); returnVal_Intercepted = MapViewOfFileEx (hFileMappingObject,dwDesiredAccess,dwFileOffsetHigh,dwFileOffsetLow,dwNumberOfBytesToMap,lpBaseAddress); error_Intercepted = GetLastError(); }__except(puts("in filter"), 1){puts("exception caught");} return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted)); }
int File::mmread() { #if POSIX return read(); #elif _WIN32 HANDLE hFile; HANDLE hFileMap; DWORD size; char *name; name = this->name->toChars(); hFile = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) goto Lerr; size = GetFileSize(hFile, NULL); //printf(" file created, size %d\n", size); hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,size,NULL); if (CloseHandle(hFile) != TRUE) goto Lerr; if (hFileMap == NULL) goto Lerr; //printf(" mapping created\n"); if (!ref) mem.free(buffer); ref = 2; buffer = (utf8_t *)MapViewOfFileEx(hFileMap, FILE_MAP_READ,0,0,size,NULL); if (CloseHandle(hFileMap) != TRUE) goto Lerr; if (buffer == NULL) // mapping view failed goto Lerr; len = size; //printf(" buffer = %p\n", buffer); return 0; Lerr: return GetLastError(); // failure #else assert(0); #endif }
TSRM_API void *shmat(int key, const void *shmaddr, int flags) { shm_pair *shm = shm_get(key, NULL); if (!shm->segment) { return (void*)-1; } shm->descriptor->shm_atime = time(NULL); shm->descriptor->shm_lpid = getpid(); shm->descriptor->shm_nattch++; shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL); return shm->addr; }
/* SYSTEM CALL: shmat(); PROTOTYPE: int shmat ( int shmid, char *shmaddr, int shmflg); RETURNS: address at which segment was attached to the process, or -1 on error: errno = EINVAL (Invalid IPC ID value or attach address passed) ENOMEM (Not enough memory to attach segment) EACCES (Permission denied) NOTES: If the addr argument is zero (0), the kernel tries to find an unmapped region. This is the recommended method. An address can be specified, but is typically only used to facilitate proprietary hardware or to resolve conflicts with other apps. The SHM_RND flag can be OR'd into the flag argument to force a passed address to be page aligned (rounds down to the nearest page size). In addition, if the SHM_RDONLY flag is OR'd in with the flag argument, then the shared memory segment will be mapped in, but marked as readonly. This call is perhaps the simplest to use. Consider this wrapper function, which is passed a valid IPC identifier for a segment, and returns the address that the segment was attached to: char *attach_segment( int shmid ) { return(shmat(shmid, 0, 0)); } Once a segment has been properly attached, and a process has a pointer to the start of that segment, reading and writing to the segment become as easy as simply referencing or dereferencing the pointer! Be careful not to lose the value of the original pointer! If this happens, you will have no way of accessing the base (start) of the segment. */ TSRM_API void *shmat(int shmid, const void *shmaddr, int shmflg) { //void *shmat(int key, const void *shmaddr, int flags) { shm_pair *shm; if ((shm = shm_get(GET_IF_EXISTS_BY_KEY, shmid, NULL)) == NULL) return (void*)-1; if (!shm->segment) { return (void*)-1; } shm->descriptor->shm_atime = time(NULL); shm->descriptor->shm_lpid = getpid(); shm->descriptor->shm_nattch++; shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL); return shm->addr; }
/* * @implemented */ LPVOID NTAPI MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) { /* Call the extended API */ return MapViewOfFileEx(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap, NULL); }
int MmapFile::open(const char* fileName) { int filedes = ::open(fileName, O_RDONLY); if (filedes < 0) { REprintf("Cannot open file"); // exit(1); return -1; } this->fileSize = ::getFileSize(fileName); if (data) { this->close(); } #ifndef _WIN32 this->data = mmap(0, this->fileSize, PROT_READ, MAP_SHARED, filedes, 0); if (this->data == MAP_FAILED) { REprintf("mmap() failed!"); // exit(1); return -1; } #else // see: // http://courses.washington.edu/hypertxt/cwb/cl/windows-mmap.c // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createfilemappinga this->handle = CreateFileMapping( (HANDLE)_get_osfhandle(filedes), NULL, // the file mapping object gets a default security descriptor PAGE_READONLY, // can also be PAGE_WRITECOPY, 0, // dwMaximumSizeHigh are 0 (zero), the maximum size of the file // mapping object is equal to the current size of the file that hFile // identifies 0, // dwMaximumSizeLow (see above) NULL); // lpName = NULL, the file mapping object is created without a // name. if (handle == NULL) { return -1; } this->data = MapViewOfFileEx(handle, FILE_MAP_READ, 0, // dwFileOffsetHigh: The high-order DWORD of // the file offset where the view is to begin 0, // dwFileOffsetLow: see above this->fileSize, // dwNumberOfBytesToMap NULL); // lpBaseAddress: A pointer to the memory // address in the calling process address // space where mapping begins. #endif return 0; }
static int zend_shared_alloc_reattach(size_t requested_size, char **error_in) { int err; void *wanted_mapping_base; char *mmap_base_file = get_mmap_base_file(); FILE *fp = fopen(mmap_base_file, "r"); MEMORY_BASIC_INFORMATION info; err = GetLastError(); if (!fp) { zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err); zend_win_error_message(ACCEL_LOG_FATAL, "Unable to open base address file", err); *error_in="fopen"; return ALLOC_FAILURE; } if (!fscanf(fp, "%p", &wanted_mapping_base)) { err = GetLastError(); zend_win_error_message(ACCEL_LOG_FATAL, "Unable to read base address", err); *error_in="read mapping base"; fclose(fp); return ALLOC_FAILURE; } fclose(fp); /* Check if the requested address space is free */ if (VirtualQuery(wanted_mapping_base, &info, sizeof(info)) == 0 || info.State != MEM_FREE || info.RegionSize < requested_size) { err = ERROR_INVALID_ADDRESS; zend_win_error_message(ACCEL_LOG_FATAL, "Unable to reattach to base address", err); return ALLOC_FAILURE; } mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, wanted_mapping_base); err = GetLastError(); if (mapping_base == NULL) { if (err == ERROR_INVALID_ADDRESS) { zend_win_error_message(ACCEL_LOG_FATAL, "Unable to reattach to base address", err); return ALLOC_FAILURE; } return ALLOC_FAIL_MAPPING; } smm_shared_globals = (zend_smm_shared_globals *) mapping_base; return SUCCESSFULLY_REATTACHED; }
void* MemoryMappedFile::createReadOnlyMap() { verify( maphandle ); stdx::lock_guard<stdx::mutex> lk(mapViewMutex); void* readOnlyMapAddress = NULL; int current_retry = 0; while (true) { LPVOID thisAddress = getNextMemoryMappedFileLocation(len); readOnlyMapAddress = MapViewOfFileEx( maphandle, // file mapping handle FILE_MAP_READ, // access 0, 0, // file offset, high and low 0, // bytes to map, 0 == all thisAddress); // address to place file if (0 == readOnlyMapAddress) { DWORD dosError = GetLastError(); ++current_retry; // If we failed to allocate a memory mapped file, try again in case we picked // an address that Windows is also trying to use for some other VM allocations if (dosError == ERROR_INVALID_ADDRESS && current_retry < 5) { continue; } log() << "MapViewOfFileEx for " << filename() << " at address " << thisAddress << " failed with error " << errnoWithDescription(dosError) << " (file size is " << len << ")" << " in MemoryMappedFile::createReadOnlyMap" << endl; fassertFailed(16165); } break; } views.push_back( readOnlyMapAddress ); return readOnlyMapAddress; }
L004125C7() { void* _t13; // _t13 _unknown_ _t14; // _t14 void* _t16; // _t16 _unknown_ _t17; // _t17 _unknown_ _t20; // _t20 _unknown_ _t22; // _t22 _unknown_ _t23; // _t23 _unknown_ _t24; // _t24 signed int _t28; // _t28 _unknown_ _t29; // _t29 _unknown_ _t31; // _t31 void* _t32; // _t32 _unknown_ _t34; // _t34 _unknown_ _t36; // _t36 _unknown_ _t38; // _t38 _t32 = 0; while(1) { _t28 = (GetProcessTimes(0, 9, 7, 23, 8) | 255) & 236; _t32 = _t32 + _t28; _push(_t28); _t13 = MapViewOfFileEx(0, 8771135, 7, 16775164, 5385011, 21); _pop(__ebx); if(_t32 >= 138331879 || _t13 != 0) { _push(_t28); _push(64); __esp = __esp - 4; *__esp = 12288; _push(0x15393); _push(0); _t16 = VirtualAlloc(); _pop(__ecx); __edi = _t16; _t34 = *__esp + 263; _push(_t16); _t23 = 482; _t29 = 1219797558; _t36 = 0; goto L4; } else { continue; } } }
void *MemArena::CreateView(s64 offset, size_t size, void *base) { #ifdef _WIN32 size = roundup(size); void *ptr = MapViewOfFileEx(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size, base); return ptr; #else void *retval = mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED | ((base == 0) ? 0 : MAP_FIXED), fd, offset); if (retval == MAP_FAILED) { NOTICE_LOG(MEMMAP, "mmap on %s (fd: %d) failed", ram_temp_file.c_str(), (int)fd); return 0; } return retval; #endif }
/* 共享内存 */ void* share_memory_Create(const char* name,size_t nbytes){ #if defined(WIN32) || defined(_WIN64) HANDLE mmap = CreateFileMappingA((HANDLE)INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,nbytes,name); if(!mmap) return NULL; return MapViewOfFileEx(mmap,FILE_MAP_ALL_ACCESS,0,0,nbytes,NULL); #else key_t key = ftok(name,0); if(key == (key_t)-1) return NULL; int id = shmget(key,nbytes,IPC_CREAT|IPC_ALL_ACCESS); if(id < 0) return NULL; void* addr = shmat(id,NULL,0); if((size_t)addr == ~0) return NULL; return addr; #endif }
bool tryMapViews(uint8_t *base) { for (auto &view : sViews) { auto lo = static_cast<DWORD>(view.start); auto hi = static_cast<DWORD>(0); auto size = static_cast<SIZE_T>(view.end - view.start); auto target = base + view.start; // Attempt to map view.address = reinterpret_cast<uint8_t*>(MapViewOfFileEx(sFile, FILE_MAP_WRITE, hi, lo, size, target)); if (!view.address) { unmapViews(); return false; } } return true; }
void* MemArena::CreateView(s64 offset, size_t size, void* base) { #ifdef _WIN32 return MapViewOfFileEx(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size, base); #else void* retval = mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED | ((base == nullptr) ? 0 : MAP_FIXED), fd, offset); if (retval == MAP_FAILED) { NOTICE_LOG(MEMMAP, "mmap failed"); return nullptr; } else { return retval; } #endif }
bool Trace::remap_backing(uint64_t new_size) { if (backing_size_ == new_size) return true; #ifdef _WIN32 while (1) { DWORD fs = GetFileSize(fd_, NULL); if (fs < new_size) { printf("WARNING: requested %" PRIu64 " bytes, but only %llx are in the file...waiting\n", new_size, fs); usleep(100 * 1000); } else { break; } } MUTEX_LOCK(backing_mutex_); HANDLE fileMapping = CreateFileMapping(fd_, NULL, PAGE_READONLY, 0, 0, NULL); backing_ = (const struct change *)MapViewOfFileEx(fileMapping, FILE_MAP_READ, 0, 0, new_size, NULL); // LEAKS!!! MUTEX_UNLOCK(backing_mutex_); #else while (1) { off_t fs = lseek(fd_, 0, SEEK_END); if ((unsigned int)fs < new_size) { printf("WARNING: requested %" PRIu64 " bytes, but only %" PRIx64 " are in the file...waiting\n", new_size, fs); usleep(100 * 1000); } else { break; } } MUTEX_LOCK(backing_mutex_); munmap((void*)backing_, backing_size_); backing_size_ = new_size; backing_ = (const struct change *)mmap(NULL, backing_size_, PROT_READ, MAP_SHARED, fd_, 0); MUTEX_UNLOCK(backing_mutex_); #endif if (backing_ == NULL) { printf("ERROR: remap_backing is about to return NULL\n"); } return (backing_ != NULL); }
void *MemArena::CreateView(s64 offset, size_t size, void *base) { #ifdef _WIN32 size = roundup(size); void *ptr = MapViewOfFileEx(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size, base); return ptr; #else void *retval = mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED | // Do not sync memory to underlying file. Linux has this by default. #ifdef __FreeBSD__ MAP_NOSYNC | #endif ((base == nullptr) ? 0 : MAP_FIXED), fd, offset); if (retval == MAP_FAILED) { LOG_ERROR(Common_Memory, "mmap failed"); return nullptr; } return retval; #endif }
int map_file(const char *filename, void *addr, int image) { HANDLE map; PBYTE view; /* Must specify FILE_SHARE_READ to open if -persist_lock_file is in use */ HANDLE file = CreateFileA(filename, GENERIC_READ | (image ? FILE_EXECUTE : 0), FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file == NULL) { int err = GetLastError(); fprintf(stderr, "Error %d opening \"%s\"\n", err, filename); return 0; } /* For image, it fails w/ ACCESS_DENIED at the map stage if we ask for * more than PAGE_READONLY, and at the view stage if we ask for * anything more than FILE_MAP_READ. */ map = CreateFileMapping(file, NULL, PAGE_READONLY | (image ? SEC_IMAGE : 0), 0, 0, NULL); if (map == NULL) { int err = GetLastError(); CloseHandle(file); fprintf(stderr, "Error %d mapping \"%s\"\n", err, filename); return 0; } view = MapViewOfFileEx(map, FILE_MAP_READ, 0, 0, 0, addr); if (view == NULL) { int err = GetLastError(); CloseHandle(map); CloseHandle(file); fprintf(stderr, "Error %d mapping view of \"%s\"\n", err, filename); return 0; } return 1; }
CReadOnlyMemMappedFile::CReadOnlyMemMappedFile(LPCTSTR pszFileName) : m_pBuf(NULL) { // define a threshold beyond which a file is mapped rather than read // into memory const int threshold = 64 * 1024 - 1; m_hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (m_hFile == INVALID_HANDLE_VALUE) throw "Could not open file"; DWORD dwSizeLow, dwSizeHigh; dwSizeLow = ::GetFileSize(m_hFile, &dwSizeHigh); ASSERT(dwSizeHigh == 0); // not actually built for use with huge files m_iFileSize = dwSizeLow; if (dwSizeLow > threshold) { // use memory map m_hMap = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL); ASSERT(m_hMap != INVALID_HANDLE_VALUE); // map the file and store the memory pointer m_pBuf = (BYTE *)MapViewOfFileEx(m_hMap, FILE_MAP_READ, 0, 0, 0, 0); } else { // <= threshold, read the entire file into memory m_pBuf = new BYTE[m_iFileSize]; DWORD dwRead; ReadFile(m_hFile, m_pBuf, m_iFileSize, &dwRead, NULL); ASSERT(dwRead == m_iFileSize); CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; // not using the file any more m_hMap = INVALID_HANDLE_VALUE; // not using a memory map } }
void* MemoryMappedFile::createReadOnlyMap() { verify( maphandle ); scoped_lock lk(mapViewMutex); LPVOID thisAddress = getNextMemoryMappedFileLocation( len ); void* readOnlyMapAddress = MapViewOfFileEx( maphandle, // file mapping handle FILE_MAP_READ, // access 0, 0, // file offset, high and low 0, // bytes to map, 0 == all thisAddress ); // address to place file if ( 0 == readOnlyMapAddress ) { DWORD dosError = GetLastError(); log() << "MapViewOfFileEx for " << filename() << " failed with error " << errnoWithDescription( dosError ) << " (file size is " << len << ")" << " in MemoryMappedFile::createReadOnlyMap" << endl; fassertFailed( 16165 ); } memconcept::is( readOnlyMapAddress, memconcept::concept::other, filename() ); views.push_back( readOnlyMapAddress ); return readOnlyMapAddress; }
hostptr_t Memory::map(hostptr_t addr, size_t count, GmacProtection prot) { hostptr_t cpuAddr = NULL; // Create anonymous file to be mapped HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)count, NULL); if(handle == NULL) return NULL; // Create a view of the file in the previously allocated virtual memory range if((cpuAddr = (hostptr_t)MapViewOfFileEx(handle, FILE_MAP_WRITE, 0, 0, (DWORD)count, addr)) == NULL) { CloseHandle(handle); return NULL; } if(Files.insert(handle, cpuAddr, count) == false) { CloseHandle(handle); return NULL; } // Make sure that the range has the requested virtual protection bits protect(cpuAddr, count, prot); return cpuAddr; }