diff --git a/out/boot.dol b/out/boot.dol index 3f7ea497..43231c65 100644 Binary files a/out/boot.dol and b/out/boot.dol differ diff --git a/source/banner/AnimatedBanner.cpp b/source/banner/AnimatedBanner.cpp index 6585504e..1f97a2b7 100644 --- a/source/banner/AnimatedBanner.cpp +++ b/source/banner/AnimatedBanner.cpp @@ -170,7 +170,7 @@ u8 *DecompressCopy(const u8 *stuff, u32 len, u32 *size) { //u32 len2 = len; // ASH0 - ret = DecompressAsh(stuff, len); + ret = DecompressAsh(stuff, len);// mem2_lo_alloc if(!ret) { gprintf("out of memory\n"); @@ -180,7 +180,7 @@ u8 *DecompressCopy(const u8 *stuff, u32 len, u32 *size) else if(isLZ77compressed(stuff)) { // LZ77 with no magic word - if(decompressLZ77content(stuff, len, &ret, &len)) + if(decompressLZ77content(stuff, len, &ret, &len))// mem2_alloc return NULL; } else if(*(u32*)(stuff) == 0x4C5A3737) // LZ77 diff --git a/source/booter/external_booter.cpp b/source/booter/external_booter.cpp index 00edd765..66b3d7fc 100644 --- a/source/booter/external_booter.cpp +++ b/source/booter/external_booter.cpp @@ -115,7 +115,7 @@ bool ExternalBooter_LoadBins(const char *binDir) if(booter_size > 0 && booter_ptr != NULL) return true; - free(extldr_ptr); + MEM2_free(extldr_ptr); extldr_ptr = NULL; extldr_size = 0; return false; diff --git a/source/channel/banner.cpp b/source/channel/banner.cpp index 600c72a3..7e2fce87 100644 --- a/source/channel/banner.cpp +++ b/source/channel/banner.cpp @@ -90,7 +90,7 @@ void Banner::SetBanner(u8 *bnr, u32 bnr_size, bool custom, bool alloc) void Banner::ClearBanner() { if(allocated == true && opening != NULL) - free(opening); + MEM2_free(opening); opening = NULL; opening_size = 0; allocated = false; @@ -177,7 +177,7 @@ void Banner::GetBanner(char *appname, bool imetOnly) if(size == 0) { if(buf != NULL) - free(buf); + MEM2_free(buf); return; } SetBanner(buf, size, false, true); diff --git a/source/channel/channel_launcher.cpp b/source/channel/channel_launcher.cpp index 7533a4d0..00cf5a2c 100644 --- a/source/channel/channel_launcher.cpp +++ b/source/channel/channel_launcher.cpp @@ -58,6 +58,7 @@ bool Identify(u64 titleid) gprintf("Generating fake ticket..."); if(!Identify_GenerateTik(&tikBuffer, &tikSize)) { + MEM2_free(tmdBuffer); gprintf("Failed!\n"); return false; } @@ -72,8 +73,8 @@ bool Identify(u64 titleid) if (certBuffer == NULL || certSize == 0) { gprintf("Failed!\n"); - free(tmdBuffer); - free(tikBuffer); + MEM2_free(tmdBuffer); + MEM2_free(tikBuffer); return false; } gprintf("Success!\n"); @@ -106,9 +107,9 @@ bool Identify(u64 titleid) } } gprintf("AHBPROT: %d, Key ID: %u\n", AHBPROT_Patched(), keyId); - free(tmdBuffer); - free(tikBuffer); - free(certBuffer); + MEM2_free(tmdBuffer); + MEM2_free(tikBuffer); + MEM2_free(certBuffer); return ret < 0 ? false : true; } diff --git a/source/channel/channels.cpp b/source/channel/channels.cpp index ed5d1280..9b048c84 100644 --- a/source/channel/channels.cpp +++ b/source/channel/channels.cpp @@ -83,7 +83,7 @@ u8 Channels::GetRequestedIOS(u64 title) if(size > 0x18B) IOS = titleTMD[0x18B]; - free(titleTMD); + MEM2_free(titleTMD); gprintf("Requested Game IOS: %i\n", IOS); return IOS; } @@ -124,7 +124,7 @@ bool Channels::GetAppNameFromTmd(u64 title, char *app, u32 *bootcontent) if(data == NULL || size < 0x208) { if(data != NULL) - free(data); + MEM2_free(data); return ret; } _tmd *tmd_file = (_tmd *)SIGNATURE_PAYLOAD((u32 *)data); @@ -140,7 +140,7 @@ bool Channels::GetAppNameFromTmd(u64 title, char *app, u32 *bootcontent) } } - free(data); + MEM2_free(data); return ret; } @@ -219,7 +219,7 @@ void Channels::Search() } } } - free(list); + MEM2_free(list); } wchar_t * Channels::GetName(int index) diff --git a/source/channel/nand_save.cpp b/source/channel/nand_save.cpp index f0fe6e0b..be88c27a 100644 --- a/source/channel/nand_save.cpp +++ b/source/channel/nand_save.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . ****************************************************************************/ #include +#include "memory/mem2.hpp" #include "nand_save.hpp" #include "nand.hpp" #include "identify.h" @@ -132,7 +133,7 @@ bool NandSave::CheckSave() ISFS_Delete(ISFS_Path); goto error; } - free(certBuffer); + MEM2_free(certBuffer); if(u8_bin != save_bin) free(u8_bin); gprintf("Created WiiFlow Save\n"); @@ -145,7 +146,7 @@ error: loaded = false; ES_AddTitleCancel(); if(certBuffer != NULL) - free(certBuffer); + MEM2_free(certBuffer); certBuffer = NULL; if(u8_bin != NULL) free(u8_bin); @@ -175,7 +176,7 @@ void NandSave::LoadSettings() useMainIOS = cur_load; } if(file != NULL) - free(file); + MEM2_free(file); strcpy(ISFS_Path, PORT_SAVE_PATH); u8 *port = ISFS_GetFile(ISFS_Path, &size, -1); @@ -185,7 +186,7 @@ void NandSave::LoadSettings() currentPort = port[0] & 1; } if(port != NULL) - free(port); + MEM2_free(port); } void NandSave::SaveIOS() diff --git a/source/gc/gc.cpp b/source/gc/gc.cpp index b4c14e0f..1397c435 100644 --- a/source/gc/gc.cpp +++ b/source/gc/gc.cpp @@ -116,7 +116,7 @@ void Nintendont_SetOptions(const char *gamePath, const char *gameID, const char break; } } - free(buffer); + MEM2_free(buffer); break; } if(NINRev == 0 || NINRev < 358) diff --git a/source/gui/coverflow.cpp b/source/gui/coverflow.cpp index f5a35a3c..5fe14329 100644 --- a/source/gui/coverflow.cpp +++ b/source/gui/coverflow.cpp @@ -2607,7 +2607,7 @@ bool CCoverFlow::cacheCoverFile(const char *wfcPath, const char *coverPath, bool TexData tex; tex.thread = true;// lets TexHandle know this texture is a cover image and in case its a homebrew icon.png m_renderingTex = &tex;// only used if cover has alpha transparency - homebrew icon.png and sourceflow smallbox - u8 textureFmt = m_compressTextures ? GX_TF_CMPR : GX_TF_RGBA8;// always GX_TF_CMPR + u8 textureFmt = m_compressTextures ? GX_TF_CMPR : GX_TF_RGB565;// always GX_TF_CMPR if(TexHandle.fromImageFile(tex, coverPath, textureFmt, 32) != TE_OK) { m_renderingTex = NULL; diff --git a/source/gui/pngu.c b/source/gui/pngu.c index ff54a11f..9fee5e8a 100644 --- a/source/gui/pngu.c +++ b/source/gui/pngu.c @@ -774,12 +774,6 @@ int PNGU_DecodeToCMPR(IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer) return PNGU_OK; } -void user_error(png_structp png_ptr, png_const_charp c) -{ - longjmp(png_ptr->jmpbuf, 1); - gprintf("%s\n", c); -} - int PNGU_EncodeFromYCbYCr(IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) { // Erase from the context any readed info @@ -1101,7 +1095,6 @@ int pngu_info (IMGCTX ctx) int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlpha, int force32bit) { u32 i; - //int mem_err = 0; // Read info if it hasn't been read before if (!ctx->infoRead) @@ -1122,21 +1115,6 @@ int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlph if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_UNKNOWN) ) return PNGU_UNSUPPORTED_COLOR_TYPE; - // error handling - jmp_buf save_jmp; - memcpy(save_jmp, png_jmpbuf(ctx->png_ptr), sizeof(save_jmp)); - if (setjmp(png_jmpbuf(ctx->png_ptr))) - { - error: - memcpy(png_jmpbuf(ctx->png_ptr), save_jmp, sizeof(save_jmp)); - free(ctx->row_pointers); - free(ctx->img_data); - pngu_free_info (ctx); - //printf("*** This is a corrupted image!!\n"); sleep(5); - //return mem_err ? PNGU_LIB_ERROR : -666; - return PNGU_LIB_ERROR; - } - png_set_error_fn(ctx->png_ptr, NULL, user_error, user_error); // Scale 16 bit samples to 8 bit if (ctx->prop.imgBitDepth == 16) png_set_strip_16 (ctx->png_ptr); @@ -1168,15 +1146,16 @@ int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlph ctx->img_data = malloc(rowbytes * ctx->prop.imgHeight); if (!ctx->img_data) { - //mem_err = 1; - goto error; + pngu_free_info (ctx); + return PNGU_LIB_ERROR; } ctx->row_pointers = malloc(sizeof (png_bytep) * ctx->prop.imgHeight); if (!ctx->row_pointers) { - //mem_err = 1; - goto error; + free (ctx->img_data); + pngu_free_info (ctx); + return PNGU_LIB_ERROR; } for (i = 0; i < ctx->prop.imgHeight; i++) @@ -1184,7 +1163,7 @@ int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlph // Transform the image and copy it to our allocated memory if (png_get_interlace_type(ctx->png_ptr, ctx->info_ptr) != PNG_INTERLACE_NONE) - png_read_image (ctx->png_ptr, ctx->row_pointers); + png_read_image (ctx->png_ptr, ctx->row_pointers); else { int rowsLeft = ctx->prop.imgHeight; @@ -1199,9 +1178,6 @@ int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlph } } - // restore default error handling - memcpy(png_jmpbuf(ctx->png_ptr), save_jmp, sizeof(save_jmp)); - // Free resources pngu_free_info(ctx); diff --git a/source/gui/texture.cpp b/source/gui/texture.cpp index d3a79eb1..41d4e6b1 100644 --- a/source/gui/texture.cpp +++ b/source/gui/texture.cpp @@ -185,7 +185,7 @@ static inline void _convertToCMPR(u8 *dst, const u8 *src, u32 width, u32 height) void STexture::Cleanup(TexData &tex) { if(tex.data != NULL) - free(tex.data);//mem2_free maybe + MEM2_free(tex.data); tex.data = NULL; tex.dataSize = 0; tex.width = 0; @@ -314,7 +314,7 @@ TexErr STexture::fromJPG(TexData &dest, const u8 *buffer, const u32 buffer_size, if(dest.data == NULL) { Cleanup(dest); - free(rawData); + MEM2_free(rawData); VideoF.dealloc(); return TE_NOMEM; } @@ -343,7 +343,7 @@ TexErr STexture::fromJPG(TexData &dest, const u8 *buffer, const u32 buffer_size, nWidth >>= 1; nHeight >>= 1; } - free(rawData); + MEM2_free(rawData); dest.maxLOD = maxLODTmp - minLODTmp; dest.width = newWidth; dest.height = newHeight; @@ -409,9 +409,12 @@ TexErr STexture::fromPNG(TexData &dest, const u8 *buffer, u8 f, u32 minMipSize, } u32 pngWidth = imgProp.imgWidth & (f == GX_TF_CMPR ? ~7u : ~3u); u32 pngHeight = imgProp.imgHeight & (f == GX_TF_CMPR ? ~7u : ~3u); + // the following 2 if's are for cover's. + // gui elements will not have mipSizes and maxLODTmp. + // only exception is lqBG gui element. if(minMipSize > 0 || maxMipSize > 0) _calcMipMaps(maxLODTmp, minLODTmp, baseWidth, baseHeight, imgProp.imgWidth, imgProp.imgHeight, minMipSize, maxMipSize); - if (maxLODTmp > 0) + if(maxLODTmp > 0) { u32 newWidth = baseWidth; u32 newHeight = baseHeight; @@ -443,7 +446,7 @@ TexErr STexture::fromPNG(TexData &dest, const u8 *buffer, u8 f, u32 minMipSize, if(dest.data == NULL) { Cleanup(dest); - free(tmpData2); + MEM2_free(tmpData2); return TE_NOMEM; } _convertToRGBA8(dest.data, tmpData2, dest.width, dest.height); @@ -471,7 +474,7 @@ TexErr STexture::fromPNG(TexData &dest, const u8 *buffer, u8 f, u32 minMipSize, if(dest.data == NULL) { Cleanup(dest); - free(tmpData2); + MEM2_free(tmpData2); return TE_NOMEM; } memset(dest.data, 0, dest.dataSize); @@ -495,13 +498,13 @@ TexErr STexture::fromPNG(TexData &dest, const u8 *buffer, u8 f, u32 minMipSize, nWidth >>= 1; nHeight >>= 1; } - free(tmpData2); + MEM2_free(tmpData2); dest.maxLOD = maxLODTmp - minLODTmp; dest.format = f; dest.width = newWidth; dest.height = newHeight; } - else + else // this is used for gui elements { dest.dataSize = GX_GetTexBufferSize(pngWidth, pngHeight, f, GX_FALSE, 0); dest.data = (u8*)MEM2_alloc(dest.dataSize); @@ -531,6 +534,8 @@ TexErr STexture::fromPNG(TexData &dest, const u8 *buffer, u8 f, u32 minMipSize, PNGU_ReleaseImageContext(ctx); } DCFlushRange(dest.data, dest.dataSize); + // reduceAlpha only used for cover region flag images on cover settings menu. + // on and off images use the same image but off has its alpha reduced. _reduceAlpha(dest, reduce_alpha); return TE_OK; } @@ -672,7 +677,7 @@ u8 *STexture::_genMipMaps(u8 *&src, u32 width, u32 height, u8 maxLOD, u32 lod0Wi memset(dstData, 0, bufSize); _resize(dstData, lod0Width, lod0Height, src, width, height); DCFlushRange(dstData, lod0Width * lod0Height * 4); - free(src); + MEM2_free(src); src = NULL; u32 nWidth = lod0Width; diff --git a/source/memory/mem2.cpp b/source/memory/mem2.cpp index 4669f474..d1d6f017 100644 --- a/source/memory/mem2.cpp +++ b/source/memory/mem2.cpp @@ -9,9 +9,10 @@ #include "gecko/gecko.hpp" #include "loader/utils.h" -static const u32 MEM2_PRIORITY_SIZE = 0x1000; +static const u32 MEM2_PRIORITY_SIZE = 0x1000;// 4k or 4096 -// Forbid the use of MEM2 through malloc +// Forbid the use of MEM2 through malloc by setting MALLOC_MEM2 = 0; if not 0 then malloc can use mem2 +// calls to malloc, memalign, calloc, free are handled below by the wrappers which decide whether to use mem1 or mem2. u32 MALLOC_MEM2 = 0; u8 *MEM1_lo_start = (u8*)0x80004000; @@ -144,6 +145,8 @@ unsigned int MEM2_freesize() return g_mem2gp.FreeSize(); } +// these wrap's are used when malloc, calloc, memalign, free are called in wiiflow. +// they decide based on if the size >= mem2_prio_size (4k) to use mem2 or mem1. using the __real means to use mem1 because MALLOC_MEM2 = 0. void *__wrap_malloc(size_t size) { void *p; diff --git a/source/memory/mem_manager.cpp b/source/memory/mem_manager.cpp index 34b949a9..a1cef216 100644 --- a/source/memory/mem_manager.cpp +++ b/source/memory/mem_manager.cpp @@ -20,7 +20,7 @@ #include "gecko/gecko.hpp" #include "loader/utils.h" -static const u32 MEM_BLOCK_SIZE = 0x80; +static const u32 MEM_BLOCK_SIZE = 0x80;// 128 MemManager::MemManager() { diff --git a/source/memory/mem_manager.hpp b/source/memory/mem_manager.hpp index 7c31723f..6161a099 100644 --- a/source/memory/mem_manager.hpp +++ b/source/memory/mem_manager.hpp @@ -22,10 +22,10 @@ enum mem_states { - MEM_FREE = (1<<0), - ALLOC_USED = (1<<1), - ALLOC_END = (1<<2), - MEM_END = (1<<3), + MEM_FREE = (1<<0),//1 + ALLOC_USED = (1<<1),//2 + ALLOC_END = (1<<2),//4 + MEM_END = (1<<3),//8 }; class MemManager { diff --git a/source/menu/menu.cpp b/source/menu/menu.cpp index 706c336b..eafe7b8e 100644 --- a/source/menu/menu.cpp +++ b/source/menu/menu.cpp @@ -1422,7 +1422,7 @@ TexData CMenu::_texture(const char *domain, const char *key, TexData &def, bool { if(freeDef && def.data != NULL) { - free(def.data); + MEM2_free(def.data); def.data = NULL; } theme.texSet[filename] = themetex; @@ -2585,7 +2585,7 @@ bool CMenu::_loadFile(u8 * &buffer, u32 &size, const char *path, const char *fil return false; if(buffer != NULL) - free(buffer); + MEM2_free(buffer); buffer = fileBuf; size = fileSize; return true; @@ -2672,7 +2672,7 @@ retry: memcpy(m_base_font, font_file, size); DCFlushRange(m_base_font, size); m_base_font_size = size; - free(u8_font_archive); + MEM2_free(u8_font_archive); } } else if(memcmp(cm[i].sha1, WFB_HASH, 20) == 0 && m_wbf1_font == NULL && m_wbf2_font == NULL) @@ -2691,7 +2691,7 @@ retry: memcpy(m_wbf2_font, font_file2, size); DCFlushRange(m_wbf2_font, size); - free(u8_font_archive); + MEM2_free(u8_font_archive); } } } @@ -2700,7 +2700,7 @@ retry: retry = true; goto retry; } - free(content); + MEM2_free(content); } void CMenu::_cleanupDefaultFont() diff --git a/source/menu/menu_about.cpp b/source/menu/menu_about.cpp index d9890a65..ebdb9251 100644 --- a/source/menu/menu_about.cpp +++ b/source/menu/menu_about.cpp @@ -120,7 +120,7 @@ void CMenu::_textAbout(void) *(txt_mem+txt_size) = '\0'; txt_file_content.fromUTF8(txt_mem); m_btnMgr.setText(m_aboutLblInfo, txt_file_content); - free(txt_mem); + MEM2_free(txt_mem); } txt_mem = NULL; return; @@ -137,7 +137,7 @@ void CMenu::_textAbout(void) *(txt_mem+txt_size) = '\0'; help_text.fromUTF8(txt_mem); m_btnMgr.setText(m_aboutLblInfo, help_text); - free(txt_mem); + MEM2_free(txt_mem); } else m_btnMgr.setText(m_aboutLblInfo, ENGLISH_TXT_W); diff --git a/source/menu/menu_download.cpp b/source/menu/menu_download.cpp index d69eba9d..e34fddcb 100644 --- a/source/menu/menu_download.cpp +++ b/source/menu/menu_download.cpp @@ -777,8 +777,8 @@ bool CMenu::_isNetworkAvailable() if(buf && size > 4) { retval = buf[4] > 0; // There is a valid connection defined. - free(buf); } + MEM2_free(buf); return retval; } diff --git a/source/menu/menu_explorer.cpp b/source/menu/menu_explorer.cpp index a17670f8..f196e786 100644 --- a/source/menu/menu_explorer.cpp +++ b/source/menu/menu_explorer.cpp @@ -68,7 +68,7 @@ void CMenu::_hideExplorer(bool instant) m_btnMgr.hide(m_explorerLblUser[i], instant); } if(elements != NULL) - free(elements); + MEM2_free(elements); elements = NULL; elements_num = 0; } @@ -381,7 +381,7 @@ void CMenu::_refreshExplorer(s8 direction) } u32 pos = 0; if(elements != NULL) - free(elements); + MEM2_free(elements); elements_num = (folderExplorer ? dirs : dirs+files); elements = (list_element*)MEM2_alloc(elements_num*sizeof(list_element)); if(dirs > 0) diff --git a/source/menu/menu_game_boot.cpp b/source/menu/menu_game_boot.cpp index 11163cac..9f19a8b9 100644 --- a/source/menu/menu_game_boot.cpp +++ b/source/menu/menu_game_boot.cpp @@ -237,14 +237,15 @@ vector CMenu::_getMetaXML(const char *bootpath) if (st.st_size > 64*1024) return args; - meta_buf = (char *) calloc(st.st_size + 1, 1);// +1 so that the buf is 0 terminated + meta_buf = (char *) MEM2_alloc(st.st_size + 1);// +1 so that the buf is 0 terminated if (!meta_buf) return args; - + memset(meta_buf, 0, st.st_size + 1); + int fd = open(meta_path, O_RDONLY); if (fd < 0) { - free(meta_buf); + MEM2_free(meta_buf); meta_buf = NULL; return args; } @@ -296,7 +297,7 @@ vector CMenu::_getMetaXML(const char *bootpath) while (p < end); } - free(meta_buf); + MEM2_free(meta_buf); meta_buf = NULL; return args; } @@ -821,6 +822,8 @@ void CMenu::_launchChannel(dir_discHdr *hdr) { setLanguage(language); ocarina_load_code(cheatFile, cheatSize); + if(cheatFile != NULL) + MEM2_free(cheatFile); NandHandle.Patch_AHB(); /* Identify maybe uses it so keep AHBPROT disabled */ PatchIOS(true, isWiiVC); /* Patch for everything */ Identify(gameTitle); @@ -1079,12 +1082,12 @@ void CMenu::_launchWii(dir_discHdr *hdr, bool dvd, bool disc_cfg) if(cheatFile != NULL) { ocarina_load_code(cheatFile, cheatSize); - free(cheatFile); + MEM2_free(cheatFile); } if(gameconfig != NULL) { app_gameconfig_load(id.c_str(), gameconfig, gameconfigSize); - free(gameconfig); + MEM2_free(gameconfig); } ExternalBooter_WiiGameSetup(wbfs_partition, dvd, patchregion, private_server, fix480p, id.c_str()); diff --git a/source/menu/menu_wad.cpp b/source/menu/menu_wad.cpp index fbc07b31..b84c25dd 100644 --- a/source/menu/menu_wad.cpp +++ b/source/menu/menu_wad.cpp @@ -109,16 +109,16 @@ int installWad(const char *path) if(uid_buf == NULL) { gprintf("No uid.sys found!\n"); - free(tmd_buf); - free(tik_buf); + MEM2_free(tmd_buf); + MEM2_free(tik_buf); return -5; } else if(uid_size % 0xC != 0) { gprintf("uid.sys size is invalid!\n"); - free(tmd_buf); - free(tik_buf); - free(uid_buf); + MEM2_free(tmd_buf); + MEM2_free(tik_buf); + MEM2_free(uid_buf); return -6; } @@ -251,8 +251,8 @@ int installWad(const char *path) isfs_WriteFile(fmt("/ticket/%08x/%08x.tik", (u32)(tid>>32), (u32)tid&0xFFFFFFFF), tik_buf, hdr.tik_len); isfs_WriteFile(fmt("/title/%08x/%08x/content/title.tmd", (u32)(tid>>32), (u32)tid&0xFFFFFFFF), tmd_buf, hdr.tmd_len); } - free(tik_buf); - free(tmd_buf); + MEM2_free(tik_buf); + MEM2_free(tmd_buf); return hash_errors; } @@ -337,7 +337,7 @@ int getTID(const char *path, u64 *tid) /* get its tid, return and free mem */ const tmd *tmd_ptr = (const tmd*)SIGNATURE_PAYLOAD(tmd_buf); (*tid) = tmd_ptr->title_id; - free(tmd_buf); + MEM2_free(tmd_buf); return 0; }