Ejemplo n.º 1
0
bool CArchive7Zip::GetFile(unsigned fid, std::vector<boost::uint8_t>& buffer)
{
	boost::mutex::scoped_lock lck(archiveLock);
	CHECK_FILE_ID(fid);
	
	// Get 7zip to decompress it
	size_t offset;
	size_t outSizeProcessed;
	SRes res;

	res = SzAr_Extract(&db, &lookStream.s, fileData[fid].fp, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp);
	if (res == SZ_OK) {
		buffer.resize(outSizeProcessed);
		memcpy(&buffer[0], (char*)outBuffer+offset, outSizeProcessed);
		return true;
	} else {
		return false;
	}
}
Ejemplo n.º 2
0
BOOL
main_unpack(CHAR *patch_file, struct MemoryStruct *patch, CHAR *grf)
{
    CHAR mes[256];

    CMemInStream memory_stream;
    CLookToRead lookStream;
    CSzArEx db;
    SRes res;
    ISzAlloc allocImp;
    ISzAlloc allocTempImp;

    memory_stream.buf = patch->memory;
    memory_stream.ptr = memory_stream.buf;
    memory_stream.size = patch->size;

    memory_stream.s.Read = &lzma_memory_read;
    memory_stream.s.Seek = &lzma_memory_seek;

    sprintf_s(mes, sizeof(mes), "Распаковка: %s...", patch_file);
    dialog_set_status(mes);

    LookToRead_CreateVTable(&lookStream, False);
    lookStream.realStream = &memory_stream.s;
    LookToRead_Init(&lookStream);

    allocImp.Alloc = SzAlloc;
    allocImp.Free = SzFree;

    allocTempImp.Alloc = SzAllocTemp;
    allocTempImp.Free = SzFreeTemp;

    SzArEx_Init(&db);
    res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
    if (res == SZ_OK)
    {
        UInt32 i;
        UInt32 blockIndex = 0xFFFFFFFF;
        Byte *outBuffer = 0;
        size_t outBufferSize = 0;
        void *grf_handle;

        // if we are working with grf we should
        // open grf-file first
        if (grf != NULL)
        {
            grf_handle = grf_load(grf, TRUE);
            if (grf_handle == NULL)
                grf_handle = grf_new(grf, TRUE);
            if (grf_handle == NULL)
            {
                SzArEx_Free(&db, &allocImp);
                sprintf_s(mes, sizeof(mes), "Невозможно ни открыть, ни создать GRF-файл: %s", grf);
                dialog_set_status(mes);
                return RES_FAIL;
            }
        }

        for (i = 0; i < db.db.NumFiles; i++)
        {
            BOOL res;
            size_t offset;
            size_t outSizeProcessed;
            CSzFileItem *f = db.db.Files + i;

            if (!f->IsDir)
            {
                res = SzAr_Extract(&db, &lookStream.s, i,
                    &blockIndex, &outBuffer, &outBufferSize,
                    &offset, &outSizeProcessed,
                    &allocImp, &allocTempImp);

                if (res != SZ_OK)
                    break;
            }

            res = (grf != NULL)
                ? main_target_grf(grf_handle, (WCHAR *)f->Name, f->IsDir, outBuffer + offset, outSizeProcessed)
                : main_target_fs((WCHAR *)f->Name, f->IsDir, outBuffer + offset, outSizeProcessed);

            if (res)
            {
                IAlloc_Free(&allocImp, outBuffer);
                SzArEx_Free(&db, &allocImp);
                return RES_FAIL;
            }
        }

        // if we're working with grf
        // close it
        if (grf != NULL)
            grf_free(grf_handle);

        IAlloc_Free(&allocImp, outBuffer);
    }

    SzArEx_Free(&db, &allocImp);

    if (res != SZ_OK)
    {
        if (res == SZ_ERROR_UNSUPPORTED)
            sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: Архив не поддерживается", patch_file);
        else if (res == SZ_ERROR_MEM)
            sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: Невозможно зарезервировать память", patch_file);
        else if (res == SZ_ERROR_CRC)
            sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: ошибка CRC", patch_file);
        else
            sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: ошибка #%d", patch_file, res);
        dialog_set_status(mes);
        return RES_FAIL;
    }

    return RES_OK;
}
Ejemplo n.º 3
0
int auxio_load_archive(const char *filename, unsigned char **dataout, int *datasize, int *dataoffset, const char *filetoload, char *outname)
{
	FILE *f;
	unsigned char idbuf[4];
	int filesFound = 0;
	std::vector<char *> filelist;	// list of files we can load in this archive

	// default case: outname is filename
	if (outname)
	{
		strcpy(outname, filename);
	}

	f = fopen(filename, "rb");

	if (!f)
	{
		return 0;	// no good
	}

	fread(idbuf, 4, 1, f);
	fclose(f);

//	printf("ID bytes %c %c %x %x\n", idbuf[0], idbuf[1], idbuf[2], idbuf[3]);

	if ((idbuf[0] == 'P') && (idbuf[1] == 'K') && (idbuf[2] == 0x03) && (idbuf[3] == 0x04))
	{	// it's zip
		unzFile zipArchive;
		char file_name[1024];
		unz_file_info info;
		int nlen;
		int ret = 0;

		zipArchive = unzOpen(filename);

		if (!zipArchive)
		{
			return 0;
		}

		unzGoToFirstFile(zipArchive);
		
		for (;;)
		{
			if (unzGetCurrentFileInfo(zipArchive, &info, file_name, 1024, NULL, 0, NULL, 0) == UNZ_OK)
			{
				if (filetoload != NULL)
				{
					if (!strcasecmp(filetoload, file_name))
					{
						int length;
						unsigned char *buffer;

						unzOpenCurrentFile(zipArchive);
					
						length = info.uncompressed_size;
						buffer = (unsigned char *)malloc(length);

				    		ret = unzReadCurrentFile(zipArchive, buffer, length);

						if (ret != length)
						{
							free(buffer);
							return 0;
						}

						unzCloseCurrentFile(zipArchive);
						unzClose(zipArchive);

						*datasize = length;
						*dataout = buffer;
						*dataoffset = 0;

						return 1;
					}
				}
				else
				{
					if (checkExtension(file_name))
					{
						char *tmpstr;

						tmpstr = (char *)malloc(strlen(file_name)+1);
						strcpy(tmpstr, file_name);

						// add to the file list
						filelist.push_back(tmpstr);
						filesFound++;
					}
				}
			}
			else
			{
				break;
			}

			ret = unzGoToNextFile(zipArchive);

			if (ret == UNZ_END_OF_LIST_OF_FILE)
			{
				break;
			}

			if (ret != UNZ_OK)
			{
				unzClose(zipArchive);
				return 0;
			}
		}

		unzClose(zipArchive);
	}
	else if ((idbuf[0] == '7') && (idbuf[1] == 'z') && (idbuf[2] == 0xbc) && (idbuf[3] == 0xaf)) 
	{	// it's 7zip
		CFileInStream archiveStream;
		SRes res;
		CSzArEx db;              /* 7z archive database structure */
		ISzAlloc allocImp;       /* memory functions for main pool */
		ISzAlloc allocTempImp;   /* memory functions for temporary pool */

		archiveStream.File = fopen(filename, "rb");
		if (!archiveStream.File)
		{
			return 0;
		}

		archiveStream.InStream.Read = SzFileReadImp;
		archiveStream.InStream.Seek = SzFileSeekImp;

		allocImp.Alloc = SzAlloc;
		allocImp.Free = SzFree;

		allocTempImp.Alloc = SzAllocTemp;
		allocTempImp.Free = SzFreeTemp;

		// init 7zip internals
		CrcGenerateTable();
		SzArEx_Init(&db);

		res = SzArEx_Open(&db, &archiveStream.InStream, &allocImp, &allocTempImp);
		if (res == SZ_OK)
		{
			int i;

			for (i = 0; i < db.db.NumFiles; i++)
			{
				CSzFileItem *item = db.db.Files + i;

				if (!item->IsDirectory)
				{
					if (filetoload != NULL)
					{
						if (!strcasecmp(filetoload, item->Name))
						{
							UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
							Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
							size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */
							size_t offset;
							size_t outSizeProcessed;

							res = SzAr_Extract(&db, &archiveStream.InStream, i, 
							        &blockIndex, &outBuffer, &outBufferSize, 
							        &offset, &outSizeProcessed, 
							        &allocImp, &allocTempImp);
						
							if (res == SZ_OK)
							{
								SzArEx_Free(&db, &allocImp);
								fclose(archiveStream.File);

								*datasize = (int)outBufferSize;
								*dataout = (unsigned char *)outBuffer;
								*dataoffset = (int)offset;

								return 1;
							}
							else
							{
								std::cout << "Error extracting 7zip!\n";
							}
						}
					}

					if (checkExtension(item->Name))
					{
						char *tmpstr;

						tmpstr = (char *)malloc(strlen(item->Name)+1);
						strcpy(tmpstr, item->Name);

						// add to the file list
						filelist.push_back(tmpstr);
						filesFound++;
					}
				}
			}

			SzArEx_Free(&db, &allocImp);
			fclose(archiveStream.File);
		}
	}
	else if ((idbuf[0] == 'R') && (idbuf[1] == 'a') && (idbuf[2] == 'r') && (idbuf[3] == '!')) 
	{	// it's rar 
		
	}

	// if we found any files and weren't forced to load them, handle accordingly
	if (filesFound)
	{
		// only 1 file found, just run it
		if (filesFound == 1)
		{
			char fname[512];
			
			strcpy(fname, filelist[0]);

			free(filelist[0]);
			filelist.clear();

			strcpy(outname, fname);

			return auxio_load_archive(filename, dataout, datasize, dataoffset, fname, NULL); 
		}
		else	// multiple files we can handle found, give the user a choice
		{
			int sel;
			char fname[512];

			filepicker = create_archselect();
			tree = lookup_widget(filepicker, "archtree");
			gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW (tree), FALSE);
			g_signal_connect(G_OBJECT(tree), "button_press_event", G_CALLBACK(check_list_double), NULL);

			// set up our tree store
			treestore = gtk_tree_store_new(1, G_TYPE_STRING);

			// attach the store to the tree	
			gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(treestore));

			// create a cell renderer using the stock text one
			renderer = gtk_cell_renderer_text_new();

			// create a display column using the renderer
			column = gtk_tree_view_column_new_with_attributes ("NES file",
		                                                   renderer,
		                                                   "text", 0,
		                                                   NULL);

			// add the display column and renderer to the tree view
			gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);

			// get the selection object too
			selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
	
			// add the filenames
			for (int fn = 0; fn < filelist.size(); fn++)
			{
				gtk_tree_store_insert(treestore, &treeiters[fn], NULL, 999999);
				gtk_tree_store_set(treestore, &treeiters[fn], 0, filelist[fn], -1);
			}

			gtk_widget_show(filepicker);

			run_picker = true;
			cancelled = false;
			while (run_picker)
			{
				gtk_main_iteration_do(FALSE);
			}

			sel = find_current_selection();

			gtk_widget_destroy(filepicker);

			// was something picked?
			if ((sel != -1) && (!cancelled))
			{
				strcpy(fname, filelist[sel]);
			}

			// free all the temp filenames
			for (int fn = 0; fn < filelist.size(); fn++)
			{
				free(filelist[fn]);
			}

			// and wipe the vector
			filelist.clear();

			if ((sel != -1) && (!cancelled))
			{
				if (outname)
				{
					strcpy(outname, fname);
				}

				return auxio_load_archive(filename, dataout, datasize, dataoffset, fname, NULL); 
			}
		}
	}

	return 0;
}