virtual void archive_list(const char *path, const service_ptr_t<file> &p_reader, archive_callback &p_out, bool p_want_readers) { if (!_extract_native_path_ptr(path)) throw exception_io_data(); AATR *aatr = pfc::new_ptr_check_t(AATR_New()); if (!AATR_Open(aatr, path)) { AATR_Delete(aatr); throw exception_io_data(); } pfc::string8_fastalloc url; for (;;) { const char *fn = AATR_NextFile(aatr); if (fn == NULL) break; t_filestats stats = { filesize_invalid, filetimestamp_invalid }; service_ptr_t<file> p_file; if (p_want_readers) { BYTE module[ASAPInfo_MAX_MODULE_LENGTH]; int module_len = AATR_ReadCurrentFile(aatr, module, sizeof(module)); p_file = new service_impl_t<reader_membuffer_simple>(module, module_len); } archive_impl::g_make_unpack_path(url, path, fn, "atr"); if (!p_out.on_entry(this, url, stats, p_file)) break; } AATR_Delete(aatr); }
static void expandFileSongs(HWND playlistWnd, int index, ASAPInfo *info) { const char *fn = (const char *) SendMessage(mod.hMainWindow, WM_WA_IPC, index, IPC_GETPLAYLISTFILE); fileinfo fi; int song = extractSongNumber(fn, fi.file); if (song >= 0) return; if (ASAPInfo_IsOurFile(fi.file)) { if (loadModule(fi.file, module, &module_len) && ASAPInfo_Load(info, fi.file, module, module_len)) { SendMessage(playlistWnd, WM_WA_IPC, IPC_PE_DELETEINDEX, index); addFileSongs(playlistWnd, &fi, info, &index); } } else if (isATR(fi.file)) { FILE *fp = fopen(fi.file, "rb"); if (fp != NULL) { AATR *aatr = AATRStdio_New(fp); if (aatr != NULL) { size_t atr_fn_len = strlen(fi.file); BOOL found = FALSE; fi.file[atr_fn_len++] = '#'; for (;;) { const char *inside_fn = AATR_NextFile(aatr); if (inside_fn == NULL) break; if (ASAPInfo_IsOurFile(inside_fn)) { module_len = AATR_ReadCurrentFile(aatr, module, sizeof(module)); if (ASAPInfo_Load(info, inside_fn, module, module_len)) { size_t inside_fn_len = strlen(inside_fn); if (atr_fn_len + inside_fn_len + 4 <= sizeof(fi.file)) { memcpy(fi.file + atr_fn_len, inside_fn, inside_fn_len + 1); if (!found) { found = TRUE; SendMessage(playlistWnd, WM_WA_IPC, IPC_PE_DELETEINDEX, index); } addFileSongs(playlistWnd, &fi, info, &index); } } } } AATR_Delete(aatr); /* Prevent Winamp crash: 1. Play anything. 2. Open an ATR with no songs. 3. If the ATR deletes itself, Winamp crashes (tested with 5.581). Solution: leave the ATR on playlist. */ if (!found && SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GETLISTLENGTH) > 1) SendMessage(playlistWnd, WM_WA_IPC, IPC_PE_DELETEINDEX, index); } fclose(fp); } } }