コード例 #1
0
ファイル: hashpak.cpp プロジェクト: Adidasman1/rehlds
/* <2ae8e> ../engine/hashpak.c:1599 */
NOXREF char *HPAK_GetItem(int item)
{
	NOXREFCHECK;

	int nCurrent;
	hash_pack_header_t header;
	hash_pack_directory_t directory;
	hash_pack_entry_t *entry;
	static char name[MAX_PATH];
	char szFileName[MAX_PATH];
	FileHandle_t fp;

	HPAK_FlushHostQueue();

	Q_snprintf(name, ARRAYSIZE(name), "%s", "custom");

	COM_DefaultExtension(name, HASHPAK_EXTENSION);
	fp = FS_Open(name, "rb");

	if (!fp)
		return "";

	FS_Read(&header, sizeof(hash_pack_header_t), 1, fp);
	if (Q_strncmp(header.szFileStamp, "HPAK", sizeof(header.szFileStamp)))
	{
		Con_Printf("%s is not an HPAK file\n", name);
		FS_Close(fp);
		return "";
	}
	if (header.version != HASHPAK_VERSION)
	{
		Con_Printf("HPAK_List:  version mismatch\n");
		FS_Close(fp);
		return "";
	}
	FS_Seek(fp, header.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
	FS_Read(&directory.nEntries, 4, 1, fp);
	if (directory.nEntries < 1 || (unsigned int)directory.nEntries > MAX_FILE_ENTRIES)
	{
		Con_Printf("ERROR: HPAK had bogus # of directory entries:  %i\n", directory.nEntries);
		FS_Close(fp);
		return "";
	}
	directory.p_rgEntries = (hash_pack_entry_t *)Mem_Malloc(sizeof(hash_pack_entry_t) * directory.nEntries);
	FS_Read(directory.p_rgEntries, sizeof(hash_pack_entry_t) * directory.nEntries, 1, fp);
	nCurrent = directory.nEntries - 1;
	if (nCurrent > item)
		nCurrent = item;
	entry = &directory.p_rgEntries[nCurrent];
	COM_FileBase(entry->resource.szFileName, szFileName);
	Q_snprintf(name, sizeof(name), "!MD5%s", MD5_Print(entry->resource.rgucMD5_hash));
	FS_Close(fp);
	Mem_Free(directory.p_rgEntries);
	return name;
}
コード例 #2
0
ファイル: hashpak.cpp プロジェクト: Adidasman1/rehlds
/* <2ab62> ../engine/hashpak.c:1200 */
void HPAK_Remove_f(void)
{
	int nIndex;
	char *pakname;

	resource_t resource;

	if (cmd_source != src_command)
		return;

	HPAK_FlushHostQueue();
	if (Cmd_Argc() != 3)
	{
		Con_Printf("Usage:  hpkremove <hpk> <index>\n");
		return;
	}

	pakname = (char *)Cmd_Argv(1);

	nIndex = Q_atoi(Cmd_Argv(2));
	if (HPAK_ResourceForIndex(pakname, nIndex, &resource))
		HPAK_RemoveLump(pakname, &resource);
	else Con_Printf("Could not locate resource %i in %s\n", nIndex, pakname);
}
コード例 #3
0
ファイル: hashpak.cpp プロジェクト: Adidasman1/rehlds
/* <2a3cb> ../engine/hashpak.c:1235 */
void HPAK_Validate_f(void)
{
	hash_pack_header_t header;
	hash_pack_directory_t directory;
	hash_pack_entry_t *entry;
	char name[MAX_PATH];
	char szFileName[MAX_PATH];
	char type[32];
	FileHandle_t fp;

	byte *pData;
	int nDataSize;
	byte md5[16];
	MD5Context_t ctx;

	if (cmd_source != src_command)
		return;

	HPAK_FlushHostQueue();

	if (Cmd_Argc() != 2)
	{
		Con_Printf("Usage:  hpkval hpkname\n");
		return;
	}

	Q_snprintf(name, ARRAYSIZE(name), "%s", Cmd_Argv(1));
#ifdef REHLDS_FIXES
	name[ARRAYSIZE(name) - 1] = 0;
#endif // REHLDS_FIXES

	COM_DefaultExtension(name, HASHPAK_EXTENSION);
	Con_Printf("Validating %s.\n", name);

	fp = FS_Open(name, "rb");
	if (!fp)
	{
		Con_Printf("ERROR: couldn't open %s.\n", name);
		return;
	}
	FS_Read(&header, sizeof(hash_pack_header_t), 1, fp);
	if (Q_strncmp(header.szFileStamp, "HPAK", sizeof(header.szFileStamp)))
	{
		Con_Printf("%s is not an HPAK file\n", name);
		FS_Close(fp);
		return;
	}
	if (header.version != HASHPAK_VERSION)
	{
		Con_Printf("hpkval:  version mismatch\n");
		FS_Close(fp);
		return;
	}
	FS_Seek(fp, header.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
	FS_Read(&directory.nEntries, 4, 1, fp);
	if (directory.nEntries < 1 || (unsigned int)directory.nEntries > MAX_FILE_ENTRIES)
	{
		Con_Printf("ERROR: HPAK had bogus # of directory entries:  %i\n", directory.nEntries);
		FS_Close(fp);
		return;
	}

	Con_Printf("# of Entries:  %i\n", directory.nEntries);
	Con_Printf("# Type Size FileName : MD5 Hash\n");

	directory.p_rgEntries = (hash_pack_entry_t *)Mem_Malloc(sizeof(hash_pack_entry_t) * directory.nEntries);
	FS_Read(directory.p_rgEntries, sizeof(hash_pack_entry_t) * directory.nEntries, 1, fp);
	for (int nCurrent = 0; nCurrent < directory.nEntries; nCurrent++)
	{
		entry = &directory.p_rgEntries[nCurrent];
		COM_FileBase(entry->resource.szFileName, szFileName);
		switch (entry->resource.type)
		{
			case t_sound:
				Q_strcpy(type, "sound");
				break;
			case t_skin:
				Q_strcpy(type, "skin");
				break;
			case t_model:
				Q_strcpy(type, "model");
				break;
			case t_decal:
				Q_strcpy(type, "decal");
				break;
			case t_generic:
				Q_strcpy(type, "generic");
				break;
			case t_eventscript:
				Q_strcpy(type, "event");
				break;
			default:
				Q_strcpy(type, "?");
				break;
		}

		Con_Printf("%i: %10s %.2fK %s:  ", nCurrent + 1, type, entry->resource.nDownloadSize / 1024.0f, szFileName);

		nDataSize = entry->nFileLength;
		if (nDataSize < 1 || (unsigned int)nDataSize >= MAX_FILE_SIZE)
			Con_Printf("Unable to MD5 hash data, size invalid:  %i\n", nDataSize);
		else
		{
			pData = (byte *)Mem_Malloc(nDataSize + 1);
			Q_memset(pData, 0, nDataSize);
			FS_Seek(fp, entry->nOffset, FILESYSTEM_SEEK_HEAD);
			FS_Read(pData, nDataSize, 1, fp);
			Q_memset(&ctx, 0, sizeof(MD5Context_t));

			MD5Init(&ctx);
			MD5Update(&ctx, pData, nDataSize);
			MD5Final(md5, &ctx);

			if (Q_memcmp(entry->resource.rgucMD5_hash, md5, sizeof(md5)) == 0)
				Con_Printf(" OK\n");
			else
			{
				Con_Printf(" MISMATCHED\n");
				Con_Printf("--------------------\n");
				Con_Printf(" File  :  %s\n", MD5_Print(entry->resource.rgucMD5_hash));
				Con_Printf(" Actual:  %s\n", MD5_Print(md5));
				Con_Printf("--------------------\n");
			}
			if (pData)
				Mem_Free(pData);
		}
	}
	FS_Close(fp);
	Mem_Free(directory.p_rgEntries);
}
コード例 #4
0
ファイル: hashpak.cpp プロジェクト: Adidasman1/rehlds
/* <2a644> ../engine/hashpak.c:945 */
void HPAK_List_f(void)
{
	hash_pack_header_t header;
	hash_pack_directory_t directory;
	hash_pack_entry_t *entry;
	char name[MAX_PATH];
	char szFileName[MAX_PATH];
	char type[32];
	FileHandle_t fp;

	if (cmd_source != src_command)
		return;

	HPAK_FlushHostQueue();

	Q_snprintf(name, ARRAYSIZE(name), "%s", Cmd_Argv(1));
#ifdef REHLDS_FIXES
	name[ARRAYSIZE(name) - 1] = 0;
#endif // REHLDS_FIXES

	COM_DefaultExtension(name, HASHPAK_EXTENSION);
	Con_Printf("Contents for %s.\n", name);

	fp = FS_Open(name, "rb");
	if (!fp)
	{
		Con_Printf("ERROR: couldn't open %s.\n", name);
		return;
	}
	FS_Read(&header, sizeof(hash_pack_header_t), 1, fp);
	if (Q_strncmp(header.szFileStamp, "HPAK", sizeof(header.szFileStamp)))
	{
		Con_Printf("%s is not an HPAK file\n", name);
		FS_Close(fp);
		return;
	}
	if (header.version != HASHPAK_VERSION)
	{
		Con_Printf("HPAK_List:  version mismatch\n");
		FS_Close(fp);
		return;
	}
	FS_Seek(fp, header.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
	FS_Read(&directory.nEntries, 4, 1, fp);
	if (directory.nEntries < 1 || (unsigned int)directory.nEntries > MAX_FILE_ENTRIES)
	{
		Con_Printf("ERROR: HPAK had bogus # of directory entries:  %i\n", directory.nEntries);
		FS_Close(fp);
		return;
	}
	Con_Printf("# of Entries:  %i\n", directory.nEntries);
	Con_Printf("# Type Size FileName : MD5 Hash\n");

	directory.p_rgEntries = (hash_pack_entry_t *)Mem_Malloc(sizeof(hash_pack_entry_t) * directory.nEntries);
	FS_Read(directory.p_rgEntries, sizeof(hash_pack_entry_t) * directory.nEntries, 1, fp);
	for (int nCurrent = 0; nCurrent < directory.nEntries; nCurrent++)
	{
		entry = &directory.p_rgEntries[nCurrent];
		COM_FileBase(entry->resource.szFileName, szFileName);
		switch (entry->resource.type)
		{
			case t_sound:
				Q_strcpy(type, "sound");
				break;
			case t_skin:
				Q_strcpy(type, "skin");
				break;
			case t_model:
				Q_strcpy(type, "model");
				break;
			case t_decal:
				Q_strcpy(type, "decal");
				break;
			case t_generic:
				Q_strcpy(type, "generic");
				break;
			case t_eventscript:
				Q_strcpy(type, "event");
				break;
			default:
				Q_strcpy(type, "?");
				break;
		}
		Con_Printf("%i: %10s %.2fK %s\n  :  %s\n", nCurrent + 1, type, entry->resource.nDownloadSize / 1024.0f, szFileName, MD5_Print(entry->resource.rgucMD5_hash));
	}
	FS_Close(fp);
	Mem_Free(directory.p_rgEntries);
}
コード例 #5
0
ファイル: hashpak.cpp プロジェクト: Adidasman1/rehlds
/* <2a974> ../engine/hashpak.c:598 */
void HPAK_RemoveLump(char *pakname, resource_t *pResource)
{
	FileHandle_t fp;
	FileHandle_t tmp;
	char szTempName[MAX_PATH];
	char szOriginalName[MAX_PATH];
	hash_pack_directory_t olddir;
	hash_pack_directory_t newdir;
	hash_pack_entry_t *oldentry;
	hash_pack_entry_t *newentry;
	int n;
	int i;

	if (pakname == NULL || *pakname == '\0' || pResource == NULL)
	{
		Con_Printf(__FUNCTION__ ":  Invalid arguments\n");
		return;
	}
	HPAK_FlushHostQueue();

#ifdef REHLDS_FIXES
	Q_strncpy(szOriginalName, pakname, ARRAYSIZE(szOriginalName) - 1);
	szOriginalName[ARRAYSIZE(szOriginalName) - 1] = 0;
	COM_DefaultExtension(szOriginalName, HASHPAK_EXTENSION);
#else

	//TODO: Not sure why Cmd_Argv(1) is used since function receives pakname parameter
	char name[MAX_PATH];
	Q_snprintf(name, ARRAYSIZE(name), "%s", Cmd_Argv(1));
	COM_DefaultExtension(name, HASHPAK_EXTENSION);
	Q_strncpy(szOriginalName, name, ARRAYSIZE(szOriginalName) - 1);
	szOriginalName[ARRAYSIZE(szOriginalName) - 1] = 0;

#endif // REHLDS_FIXES

	fp = FS_Open(szOriginalName, "rb");
	if (!fp)
	{
		Con_Printf("Error:  couldn't open HPAK file %s for removal.\n", szOriginalName);
		return;
	}
	COM_StripExtension(szOriginalName, szTempName);
	COM_DefaultExtension(szTempName, ".hp2");

	tmp = FS_Open(szTempName, "w+b");
	if (!tmp)
	{
		FS_Close(fp);
		Con_Printf("ERROR: couldn't create %s.\n", szTempName);
		return;
	}	
	FS_Seek(fp, 0, FILESYSTEM_SEEK_HEAD);
	FS_Seek(tmp, 0, FILESYSTEM_SEEK_HEAD);
	FS_Read(&hash_pack_header, sizeof(hash_pack_header_t), 1, fp);
	FS_Write(&hash_pack_header, sizeof(hash_pack_header_t), 1, tmp);
	if (Q_strncmp(hash_pack_header.szFileStamp, "HPAK", sizeof(hash_pack_header.szFileStamp)))
	{
		FS_Close(fp);
		FS_Close(tmp);
		FS_Unlink(szTempName);
		Con_Printf("%s is not an HPAK file\n", szOriginalName);
		return;
	}
	if (hash_pack_header.version != HASHPAK_VERSION)
	{
		FS_Close(fp);
		FS_Close(tmp);
		FS_Unlink(szTempName);
		Con_Printf("ERROR: HPAK version outdated\n");
		return;
	}
	FS_Seek(fp, hash_pack_header.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
	FS_Read(&olddir.nEntries, 4, 1, fp);
	if (olddir.nEntries < 1 || (unsigned int)olddir.nEntries > MAX_FILE_ENTRIES)
	{
		FS_Close(fp);
		FS_Close(tmp);
		FS_Unlink(szTempName);
		Con_Printf("ERROR: HPAK had bogus # of directory entries:  %i\n", olddir.nEntries);
		return;
	}
	if (olddir.nEntries == 1)
	{
		FS_Close(fp);
		FS_Close(tmp);
		FS_Unlink(szOriginalName);
		FS_Unlink(szTempName);
		Con_Printf("Removing final lump from HPAK, deleting HPAK:\n  %s\n", szOriginalName);
		return;
	}
	olddir.p_rgEntries = (hash_pack_entry_t *)Mem_Malloc(sizeof(hash_pack_entry_t) * olddir.nEntries);
	FS_Read(olddir.p_rgEntries, sizeof(hash_pack_entry_t) * olddir.nEntries, 1, fp);

	newdir.nEntries = olddir.nEntries - 1;
	newdir.p_rgEntries = (hash_pack_entry_t *)Mem_Malloc(sizeof(hash_pack_entry_t) * newdir.nEntries);
	if (!HPAK_FindResource(&olddir, pResource->rgucMD5_hash, NULL))
	{
		FS_Close(fp);
		FS_Close(tmp);
		FS_Unlink(szTempName);
		Mem_Free(olddir.p_rgEntries);
		Mem_Free(newdir.p_rgEntries);

		Con_Printf("ERROR: HPAK doesn't contain specified lump:  %s\n", pResource->szFileName);
		return;
	}
	Con_Printf("Removing %s from HPAK %s.\n", pResource->szFileName, szOriginalName);
	for (i = 0, n = 0; i < olddir.nEntries; i++)
	{
		oldentry = &olddir.p_rgEntries[i];

		if (Q_memcmp(olddir.p_rgEntries[i].resource.rgucMD5_hash, pResource->rgucMD5_hash, 16))
		{
			newentry = &newdir.p_rgEntries[n++];
			Q_memcpy(newentry, oldentry, sizeof(hash_pack_entry_t));
			newentry->nOffset = FS_Tell(tmp);

			FS_Seek(fp, oldentry->nOffset, FILESYSTEM_SEEK_HEAD);
			COM_CopyFileChunk(tmp, fp, newentry->nFileLength);
		}
	}
	hash_pack_header.nDirectoryOffset = FS_Tell(tmp);
	FS_Write(&newdir.nEntries, 4, 1, tmp);
	for (i = 0; i < newdir.nEntries; i++)
		FS_Write(&newdir.p_rgEntries[i], sizeof(hash_pack_entry_t), 1, tmp);

	FS_Seek(tmp, 0, FILESYSTEM_SEEK_HEAD);
	FS_Write(&hash_pack_header, sizeof(hash_pack_header_t), 1, tmp);
	FS_Close(fp);
	FS_Close(tmp);
	FS_Unlink(szOriginalName);
	FS_Rename(szTempName, szOriginalName);
	Mem_Free(olddir.p_rgEntries);
	Mem_Free(newdir.p_rgEntries);
}
コード例 #6
0
ファイル: hashpak.cpp プロジェクト: Adidasman1/rehlds
/* <2afb5> ../engine/hashpak.c:1728 */
void HPAK_ValidatePak(char *fullpakname)
{
	hash_pack_header_t header;
	hash_pack_directory_t directory;
	hash_pack_entry_t *entry;
	char szFileName[MAX_PATH];
	FileHandle_t fp;

	byte *pData;
	byte md5[16];

	MD5Context_t ctx;

	HPAK_FlushHostQueue();
	fp = FS_Open(fullpakname, "rb");

	if (!fp)
		return;

	FS_Read(&header, sizeof(hash_pack_header_t), 1, fp);

	if (header.version != HASHPAK_VERSION || Q_strncmp(header.szFileStamp, "HPAK", sizeof(header.szFileStamp)) != 0)
	{
		Con_Printf("%s is not a PAK file, deleting\n", fullpakname);
		FS_Close(fp);
		FS_RemoveFile(fullpakname, 0);
		return;
	}

	FS_Seek(fp, header.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
	FS_Read(&directory, 4, 1, fp);

	if (directory.nEntries < 1 || (unsigned int)directory.nEntries > MAX_FILE_ENTRIES)
	{
		Con_Printf("ERROR: HPAK %s had bogus # of directory entries:  %i, deleting\n", fullpakname, directory.nEntries);
		FS_Close(fp);
		FS_RemoveFile(fullpakname, 0);
		return;
	}

	directory.p_rgEntries = (hash_pack_entry_t *)Mem_Malloc(sizeof(hash_pack_entry_t) * directory.nEntries);
	FS_Read(directory.p_rgEntries, sizeof(hash_pack_entry_t) * directory.nEntries, 1, fp);
	for (int nCurrent = 0; nCurrent < directory.nEntries; nCurrent++)
	{
		entry = &directory.p_rgEntries[nCurrent];
		COM_FileBase(entry->resource.szFileName, szFileName);

		if ((unsigned int)entry->nFileLength >= MAX_FILE_SIZE)
		{
			Con_Printf("Mismatched data in HPAK file %s, deleting\n", fullpakname);
			Con_Printf("Unable to MD5 hash data lump %i, size invalid:  %i\n", nCurrent + 1, entry->nFileLength);

			FS_Close(fp);
			FS_RemoveFile(fullpakname, 0);
			Mem_Free(directory.p_rgEntries);
			return;
		}

		pData = (byte *)Mem_Malloc(entry->nFileLength + 1);

		Q_memset(pData, 0, entry->nFileLength);
		FS_Seek(fp, entry->nOffset, FILESYSTEM_SEEK_HEAD);
		FS_Read(pData, entry->nFileLength, 1, fp);
		Q_memset(&ctx, 0, sizeof(MD5Context_t));

		MD5Init(&ctx);
		MD5Update(&ctx, pData, entry->nFileLength);
		MD5Final(md5, &ctx);

		if (pData)
			Mem_Free(pData);

		if (Q_memcmp(entry->resource.rgucMD5_hash, md5, sizeof(md5)) != 0)
		{
			Con_Printf("Mismatched data in HPAK file %s, deleting\n", fullpakname);
			FS_Close(fp);
			FS_RemoveFile(fullpakname, 0);
			Mem_Free(directory.p_rgEntries);
			return;
		}
	}
	FS_Close(fp);
	Mem_Free(directory.p_rgEntries);
}
コード例 #7
0
ファイル: hashpak.cpp プロジェクト: Adidasman1/rehlds
/* <2a33c> ../engine/hashpak.c:1401 */
void HPAK_Extract_f(void)
{
	hash_pack_header_t header;
	hash_pack_directory_t directory;
	hash_pack_entry_t *entry;
	char name[MAX_PATH];
	char type[32];
	FileHandle_t fp;
	int nIndex;

	byte *pData;
	int nDataSize;
	FileHandle_t fpOutput;
	char szFileOut[MAX_PATH];

	if (cmd_source != src_command)
		return;

	HPAK_FlushHostQueue();

	if (Cmd_Argc() != 3)
	{
		Con_Printf("Usage:  hpkextract hpkname [all | single index]\n");
		return;
	}
	if (Q_stricmp(Cmd_Argv(2),"all") != 0)
	{
		nIndex = Q_atoi(Cmd_Argv(2));

#ifdef REHLDS_FIXES
		Q_snprintf(name, sizeof(name), "%s", Cmd_Argv(1));
#else
		Q_snprintf(name, 256, "%s", Cmd_Argv(1));
#endif // REHLDS_FIXES
		if (nIndex != -1)
			Con_Printf("Extracting lump %i from %s\n", nIndex, name);
	}
	else
	{
		nIndex = -1;

		Q_snprintf(name, ARRAYSIZE(name), "%s", Cmd_Argv(1));
#ifdef REHLDS_FIXES
		name[ARRAYSIZE(name) - 1] = 0;
#endif // REHLDS_FIXES

		COM_DefaultExtension(name, HASHPAK_EXTENSION);
		Con_Printf("Extracting all lumps from %s.\n", name);
	}

	fp = FS_Open(name, "rb");
	if (!fp)
	{
		Con_Printf("ERROR: couldn't open %s.\n", name);
		return;
	}
	FS_Read(&header, sizeof(hash_pack_header_t), 1, fp);
	if (Q_strncmp(header.szFileStamp, "HPAK", sizeof(header.szFileStamp)))
	{
		Con_Printf("%s is not an HPAK file\n", name);
		FS_Close(fp);
		return;
	}
	if (header.version != HASHPAK_VERSION)
	{
		Con_Printf("hpkextract:  version mismatch\n");
		FS_Close(fp);
		return;
	}
	FS_Seek(fp, header.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
	FS_Read(&directory.nEntries, 4, 1, fp);
	if (directory.nEntries < 1 || (unsigned int)directory.nEntries > MAX_FILE_ENTRIES)
	{
		Con_Printf("ERROR: HPAK had bogus # of directory entries:  %i\n", directory.nEntries);
		FS_Close(fp);
		return;
	}

	Con_Printf("# of Entries:  %i\n", directory.nEntries);
	Con_Printf("# Type Size FileName : MD5 Hash\n");

	directory.p_rgEntries = (hash_pack_entry_t *)Mem_Malloc(sizeof(hash_pack_entry_t) * directory.nEntries);
	FS_Read(directory.p_rgEntries, sizeof(hash_pack_entry_t) * directory.nEntries, 1, fp);
	for (int nCurrent = 0; nCurrent < directory.nEntries; nCurrent++)
	{
		entry = &directory.p_rgEntries[nCurrent];
		if (nIndex == -1 || nIndex == nCurrent)
		{
			COM_FileBase(entry->resource.szFileName, szFileOut);
			switch (entry->resource.type)
			{
				case t_sound:
					Q_strcpy(type, "sound");
					break;
				case t_skin:
					Q_strcpy(type, "skin");
					break;
				case t_model:
					Q_strcpy(type, "model");
					break;
				case t_decal:
					Q_strcpy(type, "decal");
					break;
				case t_generic:
					Q_strcpy(type, "generic");
					break;
				case t_eventscript:
					Q_strcpy(type, "event");
					break;
				default:
					Q_strcpy(type, "?");
					break;
			}

			Con_Printf("Extracting %i: %10s %.2fK %s\n", nCurrent, type, entry->resource.nDownloadSize / 1024.0f, szFileOut);
			nDataSize = entry->nFileLength;
			if (nDataSize < 1 || (unsigned int)nDataSize >= MAX_FILE_SIZE)
				Con_Printf("Unable to extract data, size invalid:  %s\n", nDataSize);

			else
			{
				pData = (byte *)Mem_Malloc(nDataSize + 1);
				Q_memset(pData, 0, nDataSize);
				FS_Seek(fp, entry->nOffset, FILESYSTEM_SEEK_HEAD);
				FS_Read(pData, nDataSize, 1, fp);
				Q_snprintf(szFileOut, sizeof(szFileOut), "hpklmps\\lmp%04i.wad", nCurrent);
				COM_FixSlashes(szFileOut);
				COM_CreatePath(szFileOut);
				fpOutput = FS_Open(szFileOut, "wb");
				if (fpOutput)
				{
					FS_Write(pData, nDataSize, 1, fpOutput);
					FS_Close(fpOutput);
				}
				else Con_Printf("Error creating lump file %s\n", szFileOut);
				if (pData)
					Mem_Free(pData);
			}
		}
	}

	FS_Close(fp);
	Mem_Free(directory.p_rgEntries);
}
コード例 #8
0
ファイル: hpak.c プロジェクト: DavidKnight247/xash3d
void HPAK_RemoveLump( const char *name, resource_t *resource )
{
	string		read_path;
	string		save_path;
	file_t		*f1, *f2;
	hpak_container_t	hpak_read;
	hpak_container_t	hpak_save;
	int		i, j;

	if( !name || !name[0] || !resource )
		return;

	HPAK_FlushHostQueue();

	Q_strncpy( read_path, name, sizeof( read_path ));
	FS_StripExtension( read_path );
	FS_DefaultExtension( read_path, ".hpk" );

	f1 = FS_Open( read_path, "rb", false );
	if( !f1 )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s couldn't open.\n", read_path );
		return;
	}

	Q_strncpy( save_path, read_path, sizeof( save_path ));
	FS_StripExtension( save_path );
	FS_DefaultExtension( save_path, ".hp2" );
	f2 = FS_Open( save_path, "w+b", false );
	if( !f2 )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s couldn't open.\n", save_path );
		FS_Close( f1 );
		return;
	}

	FS_Seek( f1, 0, SEEK_SET );
	FS_Seek( f2, 0, SEEK_SET );

	// header copy
	FS_Read( f1, &hash_pack_header, sizeof( hpak_header_t ));
	FS_Write( f2, &hash_pack_header, sizeof( hpak_header_t ));

	if( hash_pack_header.ident != IDCUSTOMHEADER || hash_pack_header.version != IDCUSTOM_VERSION )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s has invalid header.\n", read_path );
		FS_Close( f1 );
		FS_Close( f2 );
		FS_Delete( save_path ); // delete temp file
		return;
	}

	FS_Seek( f1, hash_pack_header.seek, SEEK_SET );
	FS_Read( f1, &hpak_read.count, sizeof( hpak_read.count ));

	if( hpak_read.count < 1 || hpak_read.count > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s has invalid number of lumps.\n", read_path );
		FS_Close( f1 );
		FS_Close( f2 );
		FS_Delete( save_path ); // delete temp file
		return;
	}

	if( hpak_read.count == 1 )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s only has one element, so it's not deleted.\n", read_path );
		FS_Close( f1 );
		FS_Close( f2 );
		FS_Delete( read_path );
		FS_Delete( save_path );
		return;
	}

	hpak_save.count = hpak_read.count - 1;
	hpak_read.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpak_read.count );
	hpak_save.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpak_save.count );

	FS_Read( f1, hpak_read.dirs, sizeof( hpak_dir_t ) * hpak_read.count );

	if( !HPAK_FindResource( &hpak_read, resource->rgucMD5_hash, NULL ))
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: Couldn't find the lump %s in hpak %s.n", resource->szFileName, read_path );
		Mem_Free( hpak_read.dirs );
		Mem_Free( hpak_save.dirs );
		FS_Close( f1 );
		FS_Close( f2 );
		FS_Delete( save_path );
		return;
	}

	MsgDev( D_INFO, "Removing lump %s from %s.\n", resource->szFileName, read_path );

	// If there's a collision, we've just corrupted this hpak.
	for( i = 0, j = 0; i < hpak_read.count; i++ )
	{
		if( !Q_memcmp( hpak_read.dirs[i].DirectoryResource.rgucMD5_hash, resource->rgucMD5_hash, 16 ))
			continue;

		hpak_save.dirs[j] = hpak_read.dirs[i];
		hpak_save.dirs[j].seek = FS_Tell( f2 );
		FS_Seek( f1, hpak_read.dirs[j].seek, SEEK_SET );
		HPAK_FileCopy( f2, f1, hpak_save.dirs[j].size );
		j++;
	}

	hash_pack_header.seek = FS_Tell( f2 );
	FS_Write( f2, &hpak_save.count, ( hpak_save.count ));

	for( i = 0; i < hpak_save.count; i++ )
	{
		FS_Write( f2, &hpak_save.dirs[i], sizeof( hpak_dir_t ));
	}

	FS_Seek( f2, 0, SEEK_SET );
	FS_Write( f2, &hash_pack_header, sizeof( hpak_header_t ));

	Mem_Free( hpak_read.dirs );
	Mem_Free( hpak_save.dirs );
	FS_Close( f1 );
	FS_Close( f2 );

	FS_Delete( read_path );
	FS_Rename( save_path, read_path );
}
コード例 #9
0
ファイル: hpak.c プロジェクト: DavidKnight247/xash3d
static qboolean HPAK_Validate( const char *filename, qboolean quiet )
{
	file_t		*f;
	hpak_dir_t	*dataDir;
	hpak_header_t	hdr;
	byte		*dataPak;
	int		i, num_lumps;
	MD5Context_t	MD5_Hash;
	string		pakname;
	resource_t	*pRes;
	char		md5[16];

	if( quiet ) HPAK_FlushHostQueue();

	// not an error - just flush queue
	if( !filename || !*filename )
		return true;

	Q_strncpy( pakname, filename, sizeof( pakname ));
	FS_StripExtension( pakname );
	FS_DefaultExtension( pakname, ".hpk" );

	f = FS_Open( pakname, "rb", false );
	if( !f )
	{
		MsgDev( D_INFO, "Couldn't find %s.\n", pakname );
		return true;
	}

	if( !quiet ) MsgDev( D_INFO, "Validating %s\n", pakname );

	FS_Read( f, &hdr, sizeof( hdr ));
	if( hdr.ident != IDCUSTOMHEADER || hdr.version != IDCUSTOM_VERSION )
	{
		MsgDev( D_ERROR, "HPAK_ValidatePak: %s does not have a valid HPAK header.\n", pakname );
		FS_Close( f );
		return false;
	}

	FS_Seek( f, hdr.seek, SEEK_SET );
	FS_Read( f, &num_lumps, sizeof( num_lumps ));

	if( num_lumps < 1 || num_lumps > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_ValidatePak: %s has too many lumps %u.\n", pakname, num_lumps );
		FS_Close( f );
		return false;
	}

	if( !quiet ) MsgDev( D_INFO, "# of Entries:  %i\n", num_lumps );

	dataDir = Z_Malloc( sizeof( hpak_dir_t ) * num_lumps );
	FS_Read( f, dataDir, sizeof( hpak_dir_t ) * num_lumps );

	if( !quiet ) MsgDev( D_INFO, "# Type Size FileName : MD5 Hash\n" );

	for( i = 0; i < num_lumps; i++ )
	{
		if( dataDir[i].size < 1 || dataDir[i].size > 131071 )
		{
			// odd max size
			MsgDev( D_ERROR, "HPAK_ValidatePak: lump %i has invalid size %s\n", i, Q_pretifymem( dataDir[i].size, 2 ));
			Mem_Free( dataDir );
			FS_Close(f);
			return false;
		}

		dataPak = Z_Malloc( dataDir[i].size );
		FS_Seek( f, dataDir[i].seek, SEEK_SET );
		FS_Read( f, dataPak, dataDir[i].size );

		Q_memset( &MD5_Hash, 0, sizeof( MD5Context_t ));
		MD5Init( &MD5_Hash );
		MD5Update( &MD5_Hash, dataPak, dataDir[i].size );
		MD5Final( md5, &MD5_Hash );

		pRes = &dataDir[i].DirectoryResource;

		MsgDev( D_INFO, "%i:      %s %s %s:   ", i, HPAK_TypeFromIndex( pRes->type ),
		Q_pretifymem( pRes->nDownloadSize, 2 ), pRes->szFileName );  

		if( Q_memcmp( md5, pRes->rgucMD5_hash, 0x10 ))
		{
			if( quiet )
			{
				MsgDev( D_ERROR, "HPAK_ValidatePak: %s has invalid checksum.\n", pakname );
				Mem_Free( dataPak );
				Mem_Free( dataDir );
				FS_Close( f );
				return false;
			}
			else MsgDev( D_INFO, "failed\n" );
		}
		else
		{
			if( !quiet ) MsgDev( D_INFO, "OK\n" );
		}

		// at this point, it's passed our checks.
		Mem_Free( dataPak );
	}

	Mem_Free( dataDir );
	FS_Close( f );
	return true;
}