/* ////////////////////////////////////////////////////////////// // SNDMEM.CXX - SOUNDxD Version 2.0 ////////////////////////////////////////////////////////////// // Memory managing functions. ///////////////////////////////////////////////////////////// */ #include "SND/snddef.h" #include "MMG.h" #include "SND/sndmem.h" #include "SND/snderr.h" #ifndef NO_ACP_MEMORY #define __DeclareGlobalVariableMmgSnd_h__ #include "SNDext/mmgsnd.h" #include "SNDext/errsnd.h" #endif //NO_ACP_MEMORY #include "sndthrd.h" typedef struct tdstBlockInfoPriv_{ char * p_cBeginBlock; char * p_cEndBlock; char * p_cFirstFree; char * p_cMaxMem; }tdstBlockInfoPriv; #ifdef MEMORY_ACCES_MANAGEMENT_MODE void SND_fn_vInitMemoryAccessManagement(); void SND_fn_vDesInitMemoryAccessManagement(); LPTOP_LEVEL_EXCEPTION_FILTER g_pfnPrevExceptionHandler; #endif void SND_fn_vCheckMemory() { #if defined(DEBUG) || !defined(NDEBUG) unsigned char ucBlockId; unsigned long ulNbMalloc; unsigned long ulNbFree; tdstBlockInfoPriv *p_stMyBlockInfo; unitAlloc * p_uaPtr; unitAlloc * p_uaFreePtr; unitAlloc uaTotalAllocatedSize; unitAlloc uaTotalFreeSize; unitAlloc uaRemainSpace; unitAlloc uaBlockSize; unitAlloc uaMaxUsed; struct tdstBlockInfoPriv_ * a_stMyBlockInfo=g_a_p_stMmgModuleBlocksInfo[g_ucSndModuleId]; unsigned char ucModuleMaxBlocksNb=E_ucSndMaxBlocksNb; Mmg_MEnterCriticalSection(); //for (ucBlockId=0; ucBlockIdp_cBeginBlock; p_uaFreePtr = (unitAlloc *)p_stMyBlockInfo->p_cFirstFree; uaTotalAllocatedSize = 0; uaTotalFreeSize = 0; ulNbFree = 0; ulNbMalloc =0; while (p_uaPtr < (unitAlloc *)p_stMyBlockInfo->p_cEndBlock){// scan all malloc if (p_uaFreePtr == p_uaPtr){// it's a free if (((unitAlloc *) *(p_uaFreePtr+1)) != (unitAlloc *) 0){ // not the last free p_uaFreePtr = (unitAlloc *) *(p_uaFreePtr+1); // go to the next free ulNbFree++; uaTotalFreeSize += *p_uaPtr; } } else{// this is a malloc uaTotalAllocatedSize += *p_uaPtr; ulNbMalloc++; } if (*(p_uaPtr)==0) { DebugBreak(); } p_uaPtr += *(p_uaPtr); }//end of while if ((p_uaPtr != (unitAlloc *)(p_stMyBlockInfo->p_cEndBlock + 1)) && (uaTotalAllocatedSize)){ snd_assert(FALSE); } else { uaBlockSize = p_stMyBlockInfo->p_cEndBlock - p_stMyBlockInfo->p_cBeginBlock +1; uaMaxUsed = p_stMyBlockInfo->p_cMaxMem - p_stMyBlockInfo->p_cBeginBlock +1; if ( (unitAlloc *) (p_uaFreePtr) == (unitAlloc *) NULL){ //all the space is used !! uaRemainSpace = 0; } else { uaRemainSpace = ((*p_uaFreePtr)<pvPtr!=NULL)) {i++;decr++;}; if (ipvPtr=ptr;decr->ulSize=size; dbg_ulNbDynMalloc++;dbg_ulSizeDynMalloc+=size; if (dbg_ulSizeDynMalloc>dbg_ulMaxSizeDynMalloc) { dbg_ulMaxSizeDynMalloc=dbg_ulSizeDynMalloc; dbg_ulIdMaxDynMalloc=dbg_ulNbDynMalloc; dbg_ulNbMaxBlocs=0;decr=&dbg_MallocHisto[0];i=0; while (ipvPtr!=NULL) dbg_ulNbMaxBlocs++; } } } } void dbg_fnReAlloc(void* oldptr,void* newptr,unsigned long size) { int i=0; tdstMallocDescriptor *decr=&dbg_MallocHisto[0]; while ((ipvPtr!=oldptr)) {i++;decr++;}; if (iulSize;dbg_ulSizeDynMalloc+=size; decr->pvPtr=newptr;decr->ulSize=size; if (dbg_ulSizeDynMalloc>dbg_ulMaxSizeDynMalloc) { dbg_ulMaxSizeDynMalloc=dbg_ulSizeDynMalloc; dbg_ulNbMaxBlocs=0;decr=&dbg_MallocHisto[0];i=0; while (ipvPtr!=NULL) dbg_ulNbMaxBlocs++; } } } } void dbg_fnFree(void* ptr) { int i=0; tdstMallocDescriptor *decr=&dbg_MallocHisto[0]; while ((ipvPtr!=ptr)) {i++;decr++;} if (iulSize;dbg_ulNbDynMalloc--; decr->pvPtr=NULL;decr->ulSize=0; } } void dbg_fnReportDynMemory() { FILE* hFile; SYSTEMTIME time; if ((hFile=fopen("sndmemrp.txt","aw"))!=NULL) { GetLocalTime(&time); fprintf(hFile,"--- Dynamic Memory used by SND ------------\xd\xa saved the %dth of %d, %d; at %2d:%2d:%2d\xd\xa",time.wMonth,time.wDay,time.wYear,time.wHour,time.wMinute,time.wSecond); fprintf(hFile,"Maximum of %d bytes segmented in %d blocks\xd\xa\xd\xa",dbg_ulMaxSizeDynMalloc,dbg_ulNbMaxBlocs); fclose(hFile); } } #endif #ifndef NO_ACP_MEMORY #define C_SND_MAINBLOCK_SIZE 100*1024 #define C_SND_MAPBLOCK_SIZE 10*1024 //---------------------------------------------------------- // InitMallocSnd:init de la librairie MallocSnd //---------------------------------------------------------- void SND_CALL SND_fn_vInitMallocSnd(void) { #ifdef MEMORY_ACCES_MANAGEMENT_MODE SND_fn_vInitMemoryAccessManagement(); #endif Mmg_M_InitMmg(Snd); Mmg_M_InitBlock(Snd,E_ucSndBlockMain,C_SND_MAINBLOCK_SIZE); Mmg_M_InitBlock(Snd,E_ucSndBlockMap,C_SND_MAPBLOCK_SIZE); SND_fn_vEnterCriticalSectionForErrorDisplay(); if (Erm_M_uwCheckError (Snd,(unsigned long)GetCurrentThreadId())) { Erm_M_ClearLastError((unsigned long)GetCurrentThreadId()); Erm_M_UpdateLastError(Snd,(unsigned long)GetCurrentThreadId(),E_uwSndMemoryBlockError, C_lErmNoDebugData,C_ucErmOpenInfoWindow, C_ucAllowStopForDebug,""); } SND_fn_vQuitCriticalSectionForErrorDisplay(); } //---------------------------------------------------------- // InitMallocSnd:init de la librairie MallocSnd //---------------------------------------------------------- void SND_CALL SND_fn_vDesInitMallocSnd(void) { #ifdef DEBUG_SON dbg_fnReportDynMemory(); #endif Mmg_M_FreeBlock(Snd,E_ucSndBlockMain); Mmg_M_FreeBlock(Snd,E_ucSndBlockMap); Mmg_M_DeleteBlock(Snd,E_ucSndBlockMain); Mmg_M_DeleteBlock(Snd,E_ucSndBlockMap); #ifdef MEMORY_ACCES_MANAGEMENT_MODE SND_fn_vDesInitMemoryAccessManagement(); #endif//MEMORY_ACCES_MANAGEMENT_MODE } //---------------------------------------------------------- // MallocSnd:allocation d'un bloc mémoire // Entrée:ulNbByte=nb d'octets à réserver // Sortie:pointeur sue le 1° octet reservé //---------------------------------------------------------- void* SND_CALL SND_fn_pvMallocSnd(unsigned long ulNbBytes) { void* ptr_temp; unsigned char ucChannel; ucChannel=Mmg_fn_ucGiveChannelId((unsigned long)GetCurrentThreadId(),0); Mmg_M_SetModeAlloc4Ch(Snd,E_ucDynamic,ucChannel ); ptr_temp=Mmg_fn_p_vAlloc4Ch(ulNbBytes,ucChannel ); SND_fn_vEnterCriticalSectionForErrorDisplay(); if (Erm_M_uwCheckError(Mmg,(unsigned long)GetCurrentThreadId())) { SND_PrintUsedStaticMemory(); Erm_M_ClearLastError((unsigned long)GetCurrentThreadId()); SND_fn_vDisplayError(E_uwSndMemoryAllocError,""); ptr_temp=NULL; } SND_fn_vQuitCriticalSectionForErrorDisplay(); Mmg_fn_vReleaseChannelId(ucChannel); #ifdef DEBUG_SON dbg_fnMalloc(ptr_temp,ulNbBytes); #endif return ptr_temp; } void* SND_CALL SND_fn_pvMallocSndEx(unsigned char id_block,unsigned long ulNbBytes) { void* ptr_temp; #ifdef MEMORY_ACCES_MANAGEMENT_MODE ptr_temp=VirtualAlloc(NULL,ulNbBytes,MEM_COMMIT,PAGE_READWRITE); if (id_block & MEMORY_ACCES_MANAGEMENT_FLAG) { } #else unsigned char ucChannel; SND_fn_vCheckMemory(); ucChannel=Mmg_fn_ucGiveChannelId((unsigned long)GetCurrentThreadId(),0); Mmg_M_SetModeAlloc4Ch(Snd,id_block,ucChannel ); ptr_temp=Mmg_fn_p_vAlloc4Ch(ulNbBytes,ucChannel ); SND_fn_vEnterCriticalSectionForErrorDisplay(); if (Erm_M_uwCheckError(Mmg,(unsigned long)GetCurrentThreadId())) { SND_PrintUsedStaticMemory(); Erm_M_ClearLastError((unsigned long)GetCurrentThreadId()); SND_fn_vDisplayError(E_uwSndMemoryAllocError,""); ptr_temp=NULL; } SND_fn_vQuitCriticalSectionForErrorDisplay(); Mmg_fn_vReleaseChannelId(ucChannel); SND_fn_vCheckMemory(); #endif //MEMORY_ACCES_MANAGEMENT_MODE return ptr_temp; } //---------------------------------------------------------- // ReAllocSnd:ré-allocation d'un bloc mémoire // Entrée:pvPtr=pointeur sur le 1° octet de la zone à réallouer // ulNbByte=nouveau nb d'octets à réserver // Sortie:pointeur sue le 1° octet reservé //---------------------------------------------------------- void* SND_CALL SND_fn_pvReAllocSnd(void* pvPtr,unsigned long ulNbBytes) { void * p_vPtr; unsigned char ucChannel; ucChannel=Mmg_fn_ucGiveChannelId((unsigned long)GetCurrentThreadId(),0); Mmg_M_SetModeAlloc4Ch(Snd,E_ucDynamic,ucChannel); p_vPtr = Mmg_fn_p_vRealloc4Ch(pvPtr,ulNbBytes,ucChannel); SND_fn_vEnterCriticalSectionForErrorDisplay(); if (Erm_M_uwCheckError(Mmg,(unsigned long)GetCurrentThreadId())) { SND_PrintUsedStaticMemory(); Erm_M_ClearLastError((unsigned long)GetCurrentThreadId()); SND_fn_vDisplayError(E_uwSndMemoryAllocError,""); } SND_fn_vQuitCriticalSectionForErrorDisplay(); Mmg_fn_vReleaseChannelId(ucChannel); #ifdef DEBUG_SON dbg_fnReAlloc(pvPtr,p_vPtr,ulNbBytes); #endif return p_vPtr; } void* SND_CALL SND_fn_pvReAllocSndEx(unsigned char id_block,void* pvPtr,unsigned long ulNbBytes) { void * newPtr; #ifdef MEMORY_ACCES_MANAGEMENT_MODE MEMORY_BASIC_INFORMATION mem_info; DWORD ret,prev_size,prev_protect; newPtr=VirtualAlloc(0,ulNbBytes,MEM_COMMIT,PAGE_READWRITE); if (!newPtr) ret=GetLastError(); else { VirtualQuery(pvPtr,&mem_info,sizeof(MEMORY_BASIC_INFORMATION)); prev_size=mem_info.RegionSize; if (!(mem_info.Protect & PAGE_READWRITE)) VirtualProtect(pvPtr,prev_size,PAGE_READWRITE,&prev_protect); CopyMemory(newPtr,pvPtr,min(ulNbBytes,prev_size)); if (!VirtualFree(pvPtr,0,MEM_RELEASE)) ret=GetLastError(); } if (id_block & MEMORY_ACCES_MANAGEMENT_FLAG) VirtualProtect(newPtr,ulNbBytes,PAGE_READONLY,&prev_protect); snd_assert(newPtr); #else unsigned char ucChannel; SND_fn_vCheckMemory(); ucChannel=Mmg_fn_ucGiveChannelId((unsigned long)GetCurrentThreadId(),0); Mmg_M_SetModeAlloc4Ch(Snd,id_block,ucChannel); newPtr = Mmg_fn_p_vRealloc4Ch(pvPtr,ulNbBytes,ucChannel ); SND_fn_vEnterCriticalSectionForErrorDisplay(); if (Erm_M_uwCheckError(Mmg,(unsigned long)GetCurrentThreadId())) { SND_PrintUsedStaticMemory(); Erm_M_ClearLastError((unsigned long)GetCurrentThreadId()); SND_fn_vDisplayError(E_uwSndMemoryAllocError,""); } SND_fn_vQuitCriticalSectionForErrorDisplay(); Mmg_fn_vReleaseChannelId(ucChannel); SND_fn_vCheckMemory(); #endif //MEMORY_ACCES_MANAGEMENT_MODE return newPtr; } //---------------------------------------------------------- // FreeSnd:libération d'un bloc mémoire // Entrée:pvPtr=pointeur sur le 1° octet de la zone à libérer //---------------------------------------------------------- void SND_CALL SND_fn_vFreeSnd(void* pvPtr) { unsigned char ucChannel; ucChannel=Mmg_fn_ucGiveChannelId((unsigned long)GetCurrentThreadId(),0); Mmg_M_SetModeAlloc4Ch(Snd,E_ucDynamic,ucChannel); Mmg_fn_vTestMallocIntegrityAt (pvPtr); Mmg_fn_vFree4Ch(pvPtr,ucChannel); SND_fn_vEnterCriticalSectionForErrorDisplay(); if (Erm_M_uwCheckError(Mmg, (unsigned long)GetCurrentThreadId())) { Erm_M_ClearLastError((unsigned long)GetCurrentThreadId()); SND_fn_vDisplayError(E_uwSndMemoryAllocError,""); } SND_fn_vQuitCriticalSectionForErrorDisplay(); Mmg_fn_vReleaseChannelId(ucChannel); #ifdef DEBUG_SON dbg_fnFree(pvPtr); #endif } void SND_CALL SND_fn_vFreeSndEx(unsigned char id_block,void* pvPtr) { #ifdef MEMORY_ACCES_MANAGEMENT_MODE VirtualFree(pvPtr,0,MEM_RELEASE); #else unsigned char ucChannel; long toto=(long)GetCurrentThreadId(); SND_fn_vCheckMemory(); ucChannel=Mmg_fn_ucGiveChannelId((unsigned long)GetCurrentThreadId(),0); Mmg_M_SetModeAlloc4Ch(Snd,id_block,ucChannel ); Mmg_fn_vTestMallocIntegrityAt (pvPtr); Mmg_fn_vFree4Ch(pvPtr,ucChannel); SND_fn_vEnterCriticalSectionForErrorDisplay(); if (Erm_M_uwCheckError(Mmg, (unsigned long)GetCurrentThreadId())) { Erm_M_ClearLastError((unsigned long)GetCurrentThreadId()); SND_fn_vDisplayError(E_uwSndMemoryAllocError,""); } SND_fn_vQuitCriticalSectionForErrorDisplay(); Mmg_fn_vReleaseChannelId(ucChannel); SND_fn_vCheckMemory(); #endif //MEMORY_ACCES_MANAGEMENT_MODE } void SND_CALL SND_fn_vResizeMemoryBlockSnd(unsigned char id,unsigned long size) { Mmg_M_InitBlock(Snd,id,size); } void SND_PrintUsedStaticMemory(void) { Mmg_M_PrintUsedStaticMemoryInModule(Snd); } #ifdef MEMORY_ACCES_MANAGEMENT_MODE //Exception filter for SND acces viloation management LONG WINAPI SND_fn_lUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo) { char texte[128]; if (ExceptionInfo->ExceptionRecord->ExceptionCode==EXCEPTION_ACCESS_VIOLATION) { sprintf(texte,"Tentative d'écrasement mémoire en %x",ExceptionInfo->ExceptionRecord->ExceptionInformation[1]); if (MessageBox(NULL,"Do you want to (attempt to) modify bloc attributs ?",texte,MB_YESNO)==IDYES) SND_fn_vLockMemoryWriteSnd_((void*)ExceptionInfo->ExceptionRecord->ExceptionInformation[1]); } else MessageBox(NULL,"ça va mal","ouîlle",MB_OK); return EXCEPTION_CONTINUE_SEARCH; } void SND_fn_vInitMemoryAccessManagement() { g_pfnPrevExceptionHandler=SetUnhandledExceptionFilter(SND_fn_lUnhandledExceptionFilter); } void SND_fn_vDesInitMemoryAccessManagement() { SetUnhandledExceptionFilter(g_pfnPrevExceptionHandler); } void SND_CALL SND_fn_vLockMemoryWriteSnd_(void* ptr) { MEMORY_BASIC_INFORMATION mem_info; DWORD prev_protect; VirtualQuery(ptr,&mem_info,sizeof(MEMORY_BASIC_INFORMATION)); snd_assert(mem_info.RegionSize); snd_assert(mem_info.Protect==PAGE_READONLY); VirtualProtect(ptr,mem_info.RegionSize,PAGE_READWRITE,&prev_protect); } void SND_CALL SND_fn_vLockMemoryReadSnd_(void* ptr) { MEMORY_BASIC_INFORMATION mem_info; DWORD prev_protect; VirtualQuery(ptr,&mem_info,sizeof(MEMORY_BASIC_INFORMATION)); snd_assert(mem_info.RegionSize); snd_assert(mem_info.Protect==PAGE_READONLY); VirtualProtect(ptr,mem_info.RegionSize,PAGE_READONLY,&prev_protect); } void SND_CALL SND_fn_vUnLockMemoryWriteSnd_(void* ptr) { MEMORY_BASIC_INFORMATION mem_info; DWORD prev_protect; VirtualQuery(ptr,&mem_info,sizeof(MEMORY_BASIC_INFORMATION)); snd_assert(mem_info.RegionSize); snd_assert(mem_info.Protect==PAGE_READWRITE); VirtualProtect(ptr,mem_info.RegionSize,PAGE_READONLY,&prev_protect); } void SND_CALL SND_fn_vUnLockMemoryReadSnd_(void* ptr) { MEMORY_BASIC_INFORMATION mem_info; DWORD prev_protect; VirtualQuery(ptr,&mem_info,sizeof(MEMORY_BASIC_INFORMATION)); snd_assert(mem_info.RegionSize); snd_assert(mem_info.Protect==PAGE_READONLY); VirtualProtect(ptr,mem_info.RegionSize,PAGE_READONLY,&prev_protect); } #endif //MEMORY_ACCES_MANAGEMENT_MODE #else //NO_ACP_MEMORY //---------------------------------------------------------- // InitMallocSnd:init de la librairie MallocSnd //---------------------------------------------------------- void SND_CALL SND_fn_vInitMallocSnd(void) { } //---------------------------------------------------------- // InitMallocSnd:init de la librairie MallocSnd //---------------------------------------------------------- void SND_CALL SND_fn_vDesInitMallocSnd(void) { } //---------------------------------------------------------- // MallocSnd:allocation d'un bloc mémoire // Entrée:ulNbByte=nb d'octets à réserver // Sortie:pointeur sue le 1° octet reservé //---------------------------------------------------------- void* SND_CALL SND_fn_pvMallocSnd(unsigned long ulNbBytes) { return VirtualAlloc(0,ulNbBytes,MEM_COMMIT,PAGE_READWRITE); } void* SND_CALL SND_fn_pvMallocSndEx(unsigned char id,unsigned long ulNbBytes) { return SND_fn_pvMallocSnd(ulNbBytes); } //---------------------------------------------------------- // ReAllocSnd:ré-allocation d'un bloc mémoire // Entrée:pvPtr=pointeur sur le 1° octet de la zone à réallouer // ulNbByte=nouveau nb d'octets à réserver // Sortie:pointeur sue le 1° octet reservé //---------------------------------------------------------- void* SND_CALL SND_fn_pvReAllocSnd(void* pvPtr,unsigned long ulNbBytes) { void *new_pvPtr; DWORD ret; MEMORY_BASIC_INFORMATION mem_info; DWORD prev_size; if (pvPtr != NULL) { new_pvPtr=VirtualAlloc(0,ulNbBytes,MEM_COMMIT,PAGE_READWRITE); if (!new_pvPtr) ret=GetLastError(); else { VirtualQuery(pvPtr,&mem_info,sizeof(MEMORY_BASIC_INFORMATION)); prev_size=mem_info.RegionSize; CopyMemory(new_pvPtr,pvPtr,min(ulNbBytes,prev_size)); if (!VirtualFree(pvPtr,0,MEM_RELEASE)) ret=GetLastError(); } } else new_pvPtr=NULL; return new_pvPtr; } void* SND_CALL SND_fn_pvReAllocSndEx(unsigned char id,void* pvPtr,unsigned long ulNbBytes) { return SND_fn_pvReAllocSnd(pvPtr,ulNbBytes); } //---------------------------------------------------------- // FreeSnd:libération d'un bloc mémoire // Entrée:pvPtr=pointeur sur le 1° octet de la zone à libérer //---------------------------------------------------------- void SND_CALL SND_fn_vFreeSnd(void* pvPtr) { DWORD ret; if (pvPtr != NULL) if (!VirtualFree(pvPtr,0,MEM_RELEASE)) ret=GetLastError(); } void SND_CALL SND_fn_vFreeSndEx(unsigned char id,void* pvPtr) { SND_fn_vFreeSnd(pvPtr); } void SND_CALL SND_fn_vResizestaticBlockSnd(int id,long size) { } void SND_PrintUsedStaticMemory (void) { } #endif //NO_ACP_MEMORY