// start mingw #ifdef __MINGW32__ #define __try #define __finally #endif // end mingw #include "MMF.h" #include using namespace std; #include #include #include #include #ifdef _WINDOWS #define snprintf _snprintf #define vsnprintf _vsnprintf #define strncasecmp _strnicmp #define strcasecmp _stricmp #else #include "MMFMutex.h" #include "../common/unix.h" #endif MMF::MMF() { SharedMemory = 0; pCanWrite = false; #ifdef _WINDOWS hMapObject = NULL; lpvMem = 0; #else lpvMem = 0; pMMFMutex = 0; m_alloc = false; #endif } MMF::~MMF() { Close(); } bool MMF::Open(const char* iName, uint32 iSize) { if (iSize < 1) { cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: iSize < 1" << endl; return false; } if (strlen(iName) < 2) { cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: strlen(iName) < 2" << endl; return false; } char MMFname[200]; memset(MMFname, 0, sizeof(MMFname)); snprintf(MMFname, sizeof(MMFname), "memfilemap_%s", iName); uint32 tmpSize = sizeof(MMF_Struct) + iSize; #ifdef _WINDOWS char MMFMutexName[200]; memset(MMFMutexName, 0, sizeof(MMFMutexName)); snprintf(MMFMutexName, sizeof(MMFMutexName), "MutexToProtectOpenMMF_%s", iName); HANDLE hMutex; hMutex = CreateMutex( NULL, // no security attributes FALSE, // initially not owned MMFMutexName); // name of mutex if (hMutex == NULL) { cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: hMutex == Null" << endl; return false; } DWORD dwWaitResult; // Request ownership of mutex. dwWaitResult = WaitForSingleObject( hMutex, // handle to mutex 2000L); // two-second time-out interval if (dwWaitResult != WAIT_OBJECT_0) { // Mutex not aquired, crap out cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: dwWaitResult != WAIT_OBJECT_0" << endl; return false; } // Finally, ready to rock. bool fInit = false; __try { hMapObject = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file NULL, // default security attributes PAGE_READWRITE, // read/write access 0, // size: high 32-bits tmpSize, // size: low 32-bits MMFname); // name of map object if (hMapObject == NULL) { cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: hMapObject == Null" << endl; return false; } // The first process to attach initializes memory. fInit = (bool) (GetLastError() != ERROR_ALREADY_EXISTS); // Get a pointer to the file-mapped shared memory. lpvMem = MapViewOfFile( hMapObject, // object to map view of FILE_MAP_WRITE, // read/write access 0, // high offset: map from 0, // low offset: beginning 0); // default: map entire file if (lpvMem == NULL) { cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: lpvMem == Null" << endl; Close(); return false; } SharedMemory = (MMF_Struct*) lpvMem; // Initialize memory if this is the first process. if (fInit) { memset(lpvMem, 0, sizeof(MMF_Struct)); pCanWrite = true; SharedMemory->Loaded = false; SharedMemory->datasize = iSize; } else { pCanWrite = false; if (SharedMemory->datasize != iSize) { cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: SharedMemory->datasize != iSize" << endl; Close(); return false; } } } // end of try block __finally { // Clean up the Mutex stuff if (!ReleaseMutex(hMutex)) { cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: !ReleaseMutex(hMutex)" << endl; Close(); return false; } } CloseHandle(hMutex); return true; #else //else, NOT WINDOWS int load_share; //int max_share = 7; key_t share_key; switch (MMFname[16]) { case 'I': load_share = 0; break; case 'N': load_share = 1; break; case 'D': load_share = 2; break; case 'S': load_share = 3; break; case 'F': load_share = 4; break; case 'L': load_share = 5; break; case 'M': load_share = 6; break; case 'O': load_share = 7; break; case 'Z': load_share = 8; break; case 'K': load_share = 9; break; #ifdef CATCH_CRASH default: cerr<<"Failed to load shared memory segment="<Loaded = false; SharedMemory->datasize = iSize; pMMFMutex->Release(this); delete pMMFMutex; return true; } } else{ cout<<"[Warning] Resize not possible"<datasize = iSize; SharedMemory->Loaded = false; pMMFMutex->Release(this); delete pMMFMutex; return true; } else if (!lpvMem){ //LogFile->write(EQEMuLog::Error, "Could not connect to shared memory and allocation of isolated memory failed."); cout<<"Could not connect to shared memory and allocation of isolated memory failed."<Release(this); delete pMMFMutex; exit(1); } pCanWrite = false; SharedMemory = (MMF_Struct*) lpvMem; if (SharedMemory->datasize != iSize) { cerr<<"SharedMemory->datasize("<datasize<<") != iSize("<Release(this); exit(1); } pMMFMutex->Release(this); delete pMMFMutex; return true; } shmid_ds mem_users; if ((shmctl(share_id, IPC_STAT, &mem_users)) != 0) { if ((lpvMem = malloc(tmpSize))) { // Success! cout<<"[Warning] Could not attach to shared memory proceeding on isolated memory"<datasize = iSize; SharedMemory->Loaded = false; pMMFMutex->Release(this); delete pMMFMutex; return true; } else { //LogFile->write(EQEMuLog::Error, "Could not connect to shared memory and allocation of isolated memory failed."); cout<<"Could not connect to shared memory and allocation of isolated memory failed."<Release(this); delete pMMFMutex; exit(1); } } lpvMem = shmat(share_id, NULL,SHM_RDONLY); pCanWrite = false; SharedMemory = (MMF_Struct*) lpvMem; //cerr << "lpvMem=" << (int)lpvMem << endl; if (lpvMem==(void *)-1 || SharedMemory->datasize != iSize) { cerr<<"SharedMemory->datasize("<datasize<<") != iSize("<Release(this); exit(1); } pMMFMutex->Release(this); delete pMMFMutex; return true; } lpvMem = shmat(share_id, NULL, SHM_R|SHM_W); memset(lpvMem, 0, sizeof(MMF_Struct)); pCanWrite = true; SharedMemory = (MMF_Struct*) lpvMem; SharedMemory->Loaded = false; SharedMemory->datasize = iSize; //} pMMFMutex->Release(this); delete pMMFMutex; return true; #endif //end NOT WINDOWS } void MMF::Close() { SharedMemory = 0; pCanWrite = false; #ifdef _WINDOWS if (lpvMem) { // Unmap shared memory from the process's address space. UnmapViewOfFile(lpvMem); lpvMem = 0; } if (hMapObject) { // Close the process's handle to the file-mapping object. CloseHandle(hMapObject); hMapObject = NULL; } #else if (lpvMem) { if (m_alloc == true) free(lpvMem); else if (shmdt(lpvMem) == -1) //LogFile->write(EQEMuLog::Error, "Warning something odd happened freeing shared memory"); cout<<"Warning something odd happened freeing shared memory"<