Subversion Repositories spk

Rev

Rev 40 | Rev 42 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 40 Rev 41
Line 206... Line 206...
206
			c->sData = new unsigned char[c->lSize + 1];
206
			c->sData = new unsigned char[c->lSize + 1];
207
			size_t readAmount = fread ( c->sData, sizeof(unsigned char), c->lSize, id );
207
			size_t readAmount = fread ( c->sData, sizeof(unsigned char), c->lSize, id );
208
			if ( readAmount != c->lSize )
208
			if ( readAmount != c->lSize )
209
                break;
209
                break;
210
 
210
 
211
			DecryptDAT(c->sData, c->lSize);
211
			DecryptDAT(c);
212
		}
212
		}
213
		fclose ( id );
213
		fclose ( id );
214
	}
214
	}
215
}
215
}
216
 
216
 
Line 339... Line 339...
339
	return ReadFileToData ( c );
339
	return ReadFileToData ( c );
340
}
340
}
341
 
341
 
342
bool CCatFile::ReadFileToData ( SInCatFile *c )
342
bool CCatFile::ReadFileToData ( SInCatFile *c )
343
{
343
{
344
	if ( !c )
-
 
345
		return false;
344
	if ( !c ) return false;
346
	size_t size = 0;
345
	size_t size = 0;
347
	c->sData = ReadData ( c, &size );
346
	if ( !c->sData ) c->sData = ReadData ( c, &size );
348
 
-
 
349
	if ( c->sData )
347
	if ( c->sData )	return true;
350
		return true;
-
 
351
 
-
 
352
	return false;
348
	return false;
353
}
349
}
354
 
350
 
355
unsigned char *CCatFile::ReadData ( SInCatFile *c, size_t *size )
351
unsigned char *CCatFile::ReadData ( SInCatFile *c, size_t *size )
356
{
352
{
357
	*size = c->lSize;
353
	*size = c->lSize;
358
 
354
 
Line 362... Line 358...
362
		fseek ( id, (long)c->lOffset, SEEK_SET );
358
		fseek ( id, (long)c->lOffset, SEEK_SET );
363
		unsigned char *data = new unsigned char[c->lSize + 1];
359
		unsigned char *data = new unsigned char[c->lSize + 1];
364
		fread ( data, sizeof(unsigned char), c->lSize, id );
360
		fread ( data, sizeof(unsigned char), c->lSize, id );
365
		*size = c->lSize;
361
		*size = c->lSize;
366
		data[c->lSize] = '\0';
362
		data[c->lSize] = '\0';
367
 
363
 
368
		DecryptDAT(data, *size);
364
		DecryptDAT(data, c->lSize);
-
 
365
		c->bDecrypted = true;
369
 
366
 
370
		fclose ( id );
367
		fclose ( id );
371
 
368
 
372
		return data;
369
		return data;
373
	}
370
	}
374
 
371
 
375
	return NULL;
372
	return NULL;
376
}
373
}
377
 
374
 
-
 
375
void CCatFile::DecryptDAT(SInCatFile *pFile) 
-
 
376
{
-
 
377
	if ( pFile->bDecrypted ) return;
-
 
378
	pFile->bDecrypted = true;
-
 
379
	this->DecryptDAT(pFile->sData, pFile->lSize);
-
 
380
}
378
void CCatFile::DecryptDAT(unsigned char *buffer, size_t size)
381
void CCatFile::DecryptDAT(unsigned char *buffer, size_t size)
379
{
382
{
380
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
383
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
381
		*pos^=0x33;
384
		*pos^=0x33;
382
	}
385
	}
Line 393... Line 396...
393
	}
396
	}
394
 
397
 
395
	return NULL;
398
	return NULL;
396
}
399
}
397
 
400
 
398
unsigned char *CCatFile::UnpackFile ( SInCatFile *c, size_t *size, bool forcepck )
401
unsigned char *CCatFile::UnpackFile ( SInCatFile *c, size_t *size)
399
{
402
{
400
	*size = 0;
403
	*size = 0;
401
	if ( !c )
404
	if ( !c )
402
		return NULL;
405
		return NULL;
403
 
406
 
404
	if ( IsDataPCK ( (const unsigned char *)c->sData, c->lSize ) || forcepck )
-
 
405
		return UnPCKData ( c->sData, c->lSize, size );
407
	this->DecryptDAT(c);
406
 
408
 
-
 
409
	int iFiletype = this->_checkFiletype(c->sData, 3);
-
 
410
 
-
 
411
	// plain file
-
 
412
	if ( iFiletype == FILETYPE_PLAIN ) {
407
	*size = c->lSize;
413
		*size = c->lSize;
408
	return c->sData;
414
		return c->sData;
-
 
415
	}
-
 
416
 
-
 
417
	//otherwise unpack it
-
 
418
 
-
 
419
//	if ( IsDataPCK ( (const unsigned char *)c->sData, c->lSize ) || forcepck )
-
 
420
	/*int iOffset = 0;
-
 
421
	if ( iFiletype == FILETYPE_PCK ) {
-
 
422
		iOffset = 1;
-
 
423
		for(size_t i=0; i < c->lSize; i++){
-
 
424
			c->sData[i] ^= magic;
-
 
425
		}
-
 
426
	}
-
 
427
	
-
 
428
 
-
 
429
	return UnPCKData ( c->sData + iOffset, c->lSize - iOffset, size );*/
-
 
430
	return UnPCKData(c->sData, c->lSize, size, (iFiletype == FILETYPE_PCK) ? true : false);
409
}
431
}
410
 
432
 
411
bool CCatFile::RemoveFile ( SInCatFile *f )
433
bool CCatFile::RemoveFile ( SInCatFile *f )
412
{
434
{
413
	if ( (m_bCreate) || (m_lFiles.empty()) )
435
	if ( (m_bCreate) || (m_lFiles.empty()) )
414
		return false;
436
		return false;
415
 
437
 
416
	if ( !f )
438
	if ( !f )
417
		return false;
439
		return false;
418
 
440
 
419
	int err = m_fDatFile.TruncateFile ( f->lOffset, f->lSize );
441
	int err = m_fDatFile.TruncateFile ( f->lOffset, f->lSize );
420
	if ( err == FILEERR_TOSMALL )
442
	if ( err == FILEERR_TOSMALL )
421
	{
443
	{
422
		if ( (int)m_fDatFile.GetFilesize() > this->GetEndOffset() )
444
		if ( (int)m_fDatFile.GetFilesize() > this->GetEndOffset() )
423
			m_fDatFile.TruncateFile( this->GetEndOffset(), m_fDatFile.GetFilesize() - this->GetEndOffset() );
445
			m_fDatFile.TruncateFile( this->GetEndOffset(), m_fDatFile.GetFilesize() - this->GetEndOffset() );
424
	}
446
	}
425
	else if ( err != FILEERR_NONE )
447
	else if ( err != FILEERR_NONE )
426
		return false;
448
		return false;
427
 
449
 
428
	// adjust the file positions
450
	// adjust the file positions
429
	int iOffset = -1;
451
	int iOffset = -1;
430
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() ) {
452
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() ) {
431
		if ( node->Data() == f ) {
453
		if ( node->Data() == f ) {
432
			iOffset = node->Data()->lOffset;
454
			iOffset = node->Data()->lOffset;
Line 454... Line 476...
454
	for ( SInCatFile *f = m_lFiles.First(); f; f = m_lFiles.Next() )
476
	for ( SInCatFile *f = m_lFiles.First(); f; f = m_lFiles.Next() )
455
	{
477
	{
456
		if ( f->sFile.Empty() )
478
		if ( f->sFile.Empty() )
457
			continue;
479
			continue;
458
		cat += f->sFile.findreplace("/", "\\") + " " + (long)f->lSize + "\n";
480
		cat += f->sFile.findreplace("/", "\\") + " " + (long)f->lSize + "\n";
459
	}
481
	}
460
 
482
 
461
	if ( !cat.Length() )
483
	if ( !cat.Length() )
462
		return false;
484
		return false;
463
 
485
 
464
	size_t len = cat.Length();
486
	size_t len = cat.Length();
465
//	if ( len % 5)
487
//	if ( len % 5)
466
//		len += (5 - (len % 5));
488
//		len += (5 - (len % 5));
467
 
489
 
468
	unsigned char *data = new unsigned char[len + 1];
490
	unsigned char *data = new unsigned char[len + 1];
469
	memcpy ( data, cat.c_str(), cat.Length() );
491
	memcpy ( data, cat.c_str(), cat.Length() );
470
 
492
 
471
	for ( size_t i = len; i > cat.Length(); i-- )
493
	for ( size_t i = len; i > cat.Length(); i-- )
472
		data[i] = '\0';
494
		data[i] = '\0';
Line 487... Line 509...
487
	else if ( ext == "txt" )
509
	else if ( ext == "txt" )
488
		return true;
510
		return true;
489
	else if ( ext == "bob" )
511
	else if ( ext == "bob" )
490
		return true;
512
		return true;
491
	else if ( ext == "bod" )
513
	else if ( ext == "bod" )
492
		return true;
514
		return true;
493
 
515
 
494
	return false;
516
	return false;
495
}
517
}
496
 
518
 
497
bool CCatFile::CheckPackedExtension ( CyString filename )
519
bool CCatFile::CheckPackedExtension ( CyString filename )
498
{
520
{
499
	CyString ext = filename.GetToken ( ".", filename.NumToken  ( "." ) ).lower();
521
	CyString ext = filename.GetToken ( ".", filename.NumToken  ( "." ) ).lower();
Line 509... Line 531...
509
}
531
}
510
 
532
 
511
CyString CCatFile::PckChangeExtension ( CyString f )
533
CyString CCatFile::PckChangeExtension ( CyString f )
512
{
534
{
513
	CFileIO fo ( f );
535
	CFileIO fo ( f );
514
	CyString ext = fo.GetFileExtension ().lower();
536
	CyString ext = fo.GetFileExtension ().lower();
515
	if ( ext == "txt" )
537
	if ( ext == "txt" )
516
		return fo.ChangeFileExtension ( "pck" );
538
		return fo.ChangeFileExtension ( "pck" );
517
	else if ( ext == "xml" )
539
	else if ( ext == "xml" )
518
		return fo.ChangeFileExtension ( "pck" );
540
		return fo.ChangeFileExtension ( "pck" );
519
	else if ( ext == "bob" )
541
	else if ( ext == "bob" )
Line 589... Line 611...
589
		unsigned char *data = new unsigned char[size + 1];
611
		unsigned char *data = new unsigned char[size + 1];
590
		fread ( data, sizeof(unsigned char), size, id );
612
		fread ( data, sizeof(unsigned char), size, id );
591
		data[size] = '\0';
613
		data[size] = '\0';
592
		fclose ( id );
614
		fclose ( id );
593
 
615
 
-
 
616
		int iFileType = this->_checkFiletype(data, 3);
594
		if ( CheckPackedExtension(to) && !IsDataPCK ( data, size ) )
617
		if ( CheckPackedExtension(to) && iFileType == FILETYPE_PLAIN )
595
		{
618
		{
596
			size_t newsize = 0;
619
			size_t newsize = 0;
597
			unsigned char *newdata = PCKData ( data, size, &newsize, bXor );
620
			unsigned char *newdata = PCKData ( data, size, &newsize, bXor );
598
 
621
 
599
			this->DecryptDAT(newdata, newsize);
-
 
600
			f->lSize = newsize;
622
			f->lSize = newsize;
-
 
623
			this->DecryptDAT(newdata, f->lSize);
601
			append = m_fDatFile.AppendDataToPos ( (const char *)newdata, newsize, f->lOffset );
624
			append = m_fDatFile.AppendDataToPos ( (const char *)newdata, newsize, f->lOffset );
602
 
625
 
603
			delete [] newdata;
626
			delete [] newdata;
604
		}
627
		}
605
		else 
628
		else 
606
		{
629
		{
607
			this->DecryptDAT(data, size);
630
			this->DecryptDAT(data, size);
608
			f->lSize = size;
631
			f->lSize = size;
609
			append = m_fDatFile.AppendDataToPos ( (const char *)data, size, f->lOffset );
632
			append = m_fDatFile.AppendDataToPos ( (const char *)data, f->lSize, f->lOffset );
610
		}
633
		}
611
 
634
 
612
		delete [] data;
635
		delete [] data;
613
	}
636
	}
614
 
637
 
615
	if ( append )
638
	if ( append )
616
	{
639
	{
617
		m_bCreate = false;
640
		m_bCreate = false;
618
		f->sFile = to;
641
		f->sFile = to;
619
		m_lFiles.push_back ( f );
642
		m_lFiles.push_back ( f );
620
		WriteCatFile ();
643
		WriteCatFile ();
621
	}
644
	}
622
	else
645
	else
623
		delete f;
646
		delete f;
624
 
647
 
625
	return true;
648
	return true;
626
}
649
}
627
 
650
 
628
bool CCatFile::AddData ( CyString catfile, unsigned char *data, size_t size, CyString to, bool pck, bool create )
651
bool CCatFile::AddData ( CyString catfile, unsigned char *data, size_t size, CyString to, bool pck, bool create )
629
{
652
{
630
	int err = Open ( catfile, "", CATREAD_CATDECRYPT, create );
653
	int err = Open ( catfile, "", CATREAD_CATDECRYPT, create );
631
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
654
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
632
		return false;
655
		return false;
Line 636... Line 659...
636
 
659
 
637
int CCatFile::GetEndOffset()
660
int CCatFile::GetEndOffset()
638
{
661
{
639
	if ( m_lFiles.empty() )
662
	if ( m_lFiles.empty() )
640
		return 0;
663
		return 0;
641
	else
664
	else
642
		return m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize;
665
		return m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize;
643
}
666
}
644
 
667
 
645
 
668
 
646
bool CCatFile::AppendData ( unsigned char *data, size_t size, CyString to, bool pck, bool bXor )
669
bool CCatFile::AppendData ( unsigned char *data, size_t size, CyString to, bool pck, bool bXor )
Line 676... Line 699...
676
 
699
 
677
	// if file extension is packed but not the file, then pack it, "pck" forces it to be packed unless it already is
700
	// if file extension is packed but not the file, then pack it, "pck" forces it to be packed unless it already is
678
 
701
 
679
	f->lSize = size;
702
	f->lSize = size;
680
	if ( (((pck) && (CheckExtensionPck (to))) || ((CheckPackedExtension ( to )))) && (!IsDataPCK ( data, size )) )
703
	if ( (((pck) && (CheckExtensionPck (to))) || ((CheckPackedExtension ( to )))) && (!IsDataPCK ( data, size )) )
681
	{
704
	{
682
		to = PckChangeExtension ( to );
705
		to = PckChangeExtension ( to );
683
 
706
 
684
		if ( !m_lFiles.empty() )
707
		if ( !m_lFiles.empty() )
685
		{
708
		{
686
			SInCatFile *f = FindData ( to );
709
			SInCatFile *f = FindData ( to );
Line 786... Line 809...
786
		m_iError = CATERR_NOFILE;
809
		m_iError = CATERR_NOFILE;
787
		return false;
810
		return false;
788
	}
811
	}
789
 
812
 
790
	return ExtractFile ( f, to, preserve );
813
	return ExtractFile ( f, to, preserve );
-
 
814
}
-
 
815
 
-
 
816
int CCatFile::_checkFiletype(const unsigned char *pBuffer, int iSize)
-
 
817
{
-
 
818
	if(iSize >= 3) {
-
 
819
		unsigned char magic = pBuffer[0] ^ 0xC8;
-
 
820
		if( (pBuffer[1] ^ magic) == 0x1F && (pBuffer[2] ^ magic) == 0x8B) {
-
 
821
			return FILETYPE_PCK;
-
 
822
		}
-
 
823
	}
-
 
824
 
-
 
825
	if ( iSize >= 2 && (pBuffer[0] == 0x1F && pBuffer[1] == 0x8B) ) {
-
 
826
		return FILETYPE_DEFLATE;
-
 
827
	}	
-
 
828
 
-
 
829
	return FILETYPE_PLAIN;
791
}
830
}
792
 
831
 
793
bool CCatFile::ExtractFile ( SInCatFile *f, CyString to, bool preserve )
832
bool CCatFile::ExtractFile ( SInCatFile *f, CyString to, bool preserve )
794
{
833
{
795
	unsigned char *data = 0;
834
	unsigned char *data = 0;
796
	size_t size = 0;
835
	size_t size = 0;
797
 
836
 
798
	// load the data from file
837
	// load the data from file
799
	ReadFileToData ( f );
838
	ReadFileToData ( f );
800
 
839
 
801
	data = UnpackFile ( f, &size, CheckPackedExtension(f->sFile) );
840
	data = this->UnpackFile(f, &size);
802
	if ( !data )
841
	if ( !data )
803
	{
842
	{
804
		m_iError = CATERR_CANTREAD;
843
		m_iError = CATERR_CANTREAD;
805
		return false;
844
		return false;
806
	}
845
	}