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);
	}
Exemple #2
0
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);
		}
	}
}