/*
===================
qboolean CRC_File(unsigned short *crcvalue, char *pszFileName)

  Computes CRC for given file.  If there is an error opening/reading the file, returns false,
  otherwise returns true and sets the crc value passed to it.  The value should be initialized
  with CRC_Init
 ==================
 */
bool CRC_File(CRC32_t *crcvalue, const char *pszFileName)
{
	// Always re-init the CRC buffer
	CRC32_Init( crcvalue );

	FileHandle_t fp;
	byte chunk[1024];
	int nBytesRead;
	
	int nSize;

	nSize = COM_OpenFile(pszFileName, &fp);
	if ( !fp || ( nSize == -1 ) )
		return FALSE;

	// Now read in 1K chunks
	while (nSize > 0)
	{
		if (nSize > 1024)
			nBytesRead = g_pFileSystem->Read(chunk, 1024, fp);
		else
			nBytesRead = g_pFileSystem->Read(chunk, nSize, fp);

		// If any data was received, CRC it.
		if (nBytesRead > 0)
		{
			nSize -= nBytesRead;
			CRC32_ProcessBuffer(crcvalue, chunk, nBytesRead);
		}

		// We we are end of file, break loop and return
		if ( g_pFileSystem->EndOfFile( fp ) )
		{
			g_pFileSystem->Close( fp );
			fp = 0;
			break;
		}
		// If there was a disk error, indicate failure.
		else if ( !g_pFileSystem->IsOk(fp) )
		{
			if ( fp )
				g_pFileSystem->Close(fp);
			return FALSE;
		}
	}	

	if ( fp )
		g_pFileSystem->Close(fp);
	return TRUE;
}
Esempio n. 2
0
int Mod_FindExternalVIS (loadedfile_t *brush_fileinfo)
{
	char	visfilename[1024];
	int		fhandle;
	int		len, i, pos;
	searchpath_t	*s_vis;
	vispatch_t	header;
	char	mapname[VISPATCH_MAPNAME_LENGTH+5];	// + ".vis" + EoS

	fhandle = -1;

	if (external_vis->value)
	{
		// check for a .VIS file
		strcpy(visfilename, loadmodel->name);
		COM_StripExtension(visfilename, visfilename);
		strcat(visfilename, ".vis");

		len = COM_OpenFile (visfilename, &fhandle, &s_vis);
		if (fhandle == -1)	// check for a .VIS file with map's directory name (e.g. ID1.VIS)
		{
			strcpy(visfilename, "maps/");
			strcat(visfilename, COM_SkipPath(brush_fileinfo->path->filename));
			strcat(visfilename, ".vis");
			len = COM_OpenFile (visfilename, &fhandle, &s_vis);
		}

		if (fhandle >= 0)
		{
			// check file for size
			if (len <= 0)
			{
				COM_CloseFile(fhandle);
				fhandle = -1;
			}
		}

		if (fhandle >= 0)
		{
			// search map in visfile
			strncpy(mapname, loadname, VISPATCH_MAPNAME_LENGTH);
			mapname[VISPATCH_MAPNAME_LENGTH] = 0;
			strcat(mapname, ".bsp");

			pos = 0;
			while ((i = Sys_FileRead (fhandle, &header, sizeof(struct vispatch_s))) == sizeof(struct vispatch_s))
			{
				header.filelen = LittleLong(header.filelen);

				pos += i;

				if (!Q_strncasecmp (header.mapname, mapname, VISPATCH_MAPNAME_LENGTH))	// found
				{
					break;
				}

				pos += header.filelen;

				Sys_FileSeek(fhandle, pos);
			}

			if (i != sizeof(struct vispatch_s))
			{
				COM_CloseFile(fhandle);
				fhandle = -1;
			}
		}

		if (fhandle >= 0)
		{
			Con_DPrintf("%s for %s loaded from %s\n", visfilename, mapname, s_vis->pack ? s_vis->pack->filename : s_vis->filename);
		}
	}

	return fhandle;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : digest[16] - 
//			*pszFileName - 
//			bSeed - 
//			seed[4] - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool MD5_Hash_File(unsigned char digest[16], char *pszFileName, bool bSeed /* = FALSE */, unsigned int seed[4] /* = NULL */)
{
	FileHandle_t fp;
	byte chunk[1024];
	int nBytesRead;
	MD5Context_t ctx;
	
	int nSize;

	nSize = COM_OpenFile( pszFileName, &fp );
	if ( !fp || ( nSize == -1 ) )
		return false;

	memset(&ctx, 0, sizeof(MD5Context_t));

	MD5Init(&ctx);

	if (bSeed)
	{
		// Seed the hash with the seed value
		MD5Update( &ctx, (const unsigned char *)&seed[0], 16 );
	}

	// Now read in 1K chunks
	while (nSize > 0)
	{
		if (nSize > 1024)
			nBytesRead = g_pFileSystem->Read(chunk, 1024, fp);
		else
			nBytesRead = g_pFileSystem->Read(chunk, nSize, fp);

		// If any data was received, CRC it.
		if (nBytesRead > 0)
		{
			nSize -= nBytesRead;
			MD5Update(&ctx, chunk, nBytesRead);
		}

		// We we are end of file, break loop and return
		if ( g_pFileSystem->EndOfFile( fp ) )
		{
			g_pFileSystem->Close( fp );
			fp = NULL;
			break;
		}
		// If there was a disk error, indicate failure.
		else if ( !g_pFileSystem->IsOk(fp) )
		{
			if ( fp )
				g_pFileSystem->Close(fp);
			return FALSE;
		}
	}	

	if ( fp )
		g_pFileSystem->Close(fp);

	MD5Final(digest, &ctx);

	return TRUE;
}
/*
===================
qboolean CRC_MapFile(unsigned short *crcvalue, char *pszFileName)

  Computes CRC for given map file.  If there is an error opening/reading the file, returns false,
  otherwise returns true and sets the crc value passed to it.  The value should be initialized
  with CRC_Init

  For map (.bsp) files, the entity lump is not included in the CRC.
  //FIXME make this work
 ==================
 */
bool CRC_MapFile(CRC32_t *crcvalue, const char *pszFileName)
{
	FileHandle_t fp;
	byte chunk[1024];
	int i, l;
	int nBytesRead;
	dheader_t	header;
	int nSize;
	lump_t *curLump;
	long startOfs;

	nSize = COM_OpenFile(pszFileName, &fp);
	if ( !fp || ( nSize == -1 ) )
		return false;

	startOfs = g_pFileSystem->Tell(fp);

	// Don't CRC the header.
	if (g_pFileSystem->Read(&header, sizeof(dheader_t), fp) == 0)
	{
		Con_Printf("Could not read BSP header for map [%s].\n", pszFileName);
		g_pFileSystem->Close(fp);
		return false;
	}

	i = LittleLong (header.version);
	if ( i != BSPVERSION )
	{
		g_pFileSystem->Close(fp);
		Con_Printf("Map [%s] has incorrect BSP version (%i should be %i).\n", pszFileName, i, BSPVERSION);
		return false;
	}

	// CRC across all lumps except for the Entities lump
	for (l = 0; l < HEADER_LUMPS; l++)
	{
		if (l == LUMP_ENTITIES)
			continue;

		curLump = &header.lumps[l];
		nSize = curLump->filelen;

		g_pFileSystem->Seek( fp, startOfs + curLump->fileofs, FILESYSTEM_SEEK_HEAD );

		// Now read in 1K chunks
		while (nSize > 0)
		{
			if (nSize > 1024)
				nBytesRead = g_pFileSystem->Read(chunk, 1024, fp);
			else
				nBytesRead = g_pFileSystem->Read(chunk, nSize, fp);

			// If any data was received, CRC it.
			if (nBytesRead > 0)
			{
				nSize -= nBytesRead;
				CRC32_ProcessBuffer(crcvalue, chunk, nBytesRead);
			}

			// If there was a disk error, indicate failure.
			if ( !g_pFileSystem->IsOk(fp) )
			{
				if ( fp )
					g_pFileSystem->Close(fp);
				return false;
			}
		}	
	}
	
	if ( fp )
		g_pFileSystem->Close(fp);
	return true;
}