Subversion Repositories spk

Rev

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

Rev 160 Rev 181
Line 270... Line 270...
270
	while ( m_sData[num] != '\0' ) {
270
	while ( m_sData[num] != '\0' ) {
271
		if ( m_sData[num] == '\n' ) {
271
		if ( m_sData[num] == '\n' ) {
272
			m_sData[num] = 0;
272
			m_sData[num] = 0;
273
			if ( spacePos != -1 )
273
			if ( spacePos != -1 )
274
			{
274
			{
275
				CyString file;
275
				Utils::String file;
276
				int size = 0;
276
				int size = 0;
277
 
277
 
278
				m_sData[spacePos] = '\0';
278
				m_sData[spacePos] = '\0';
279
				file = (char *)data;
279
				file = (char *)data;
280
				data = (m_sData + (spacePos + 1));
280
				data = (m_sData + (spacePos + 1));
281
				if ( !CyString((char *)data).IsNumber() )
281
				if ( !Utils::String((char *)data).isNumber() )
282
					size = 0;
282
					size = 0;
283
				else
283
				else
284
					size = atoi((const char *)data);
284
					size = atoi((const char *)data);
285
 
285
 
286
				if ( size )
286
				if ( size )
Line 349... Line 349...
349
	m_sData = NULL;
349
	m_sData = NULL;
350
	m_iDataType = CATFILE_NONE;
350
	m_iDataType = CATFILE_NONE;
351
	m_lSize = 0;
351
	m_lSize = 0;
352
}
352
}
353
 
353
 
354
bool CCatFile::ReadFileToData ( CyString filename )
354
bool CCatFile::readFileToData(const Utils::String &filename)
355
{
355
{
356
	SInCatFile *c = FindData ( filename );
356
	SInCatFile *c = findData(filename);
357
	return ReadFileToData ( c );
357
	return readFileToData(c);
358
}
358
}
359
 
359
 
360
bool CCatFile::ReadFileToData ( SInCatFile *c )
360
bool CCatFile::readFileToData(SInCatFile *c)
361
{
361
{
362
	if ( !c ) return false;
362
	if ( !c ) return false;
363
	size_t size = 0;
363
	size_t size = 0;
364
	if ( !c->sData ) c->sData = readData ( c, &size );
364
	if ( !c->sData ) c->sData = readData ( c, &size );
365
	if ( c->sData )	return true;
365
	if ( c->sData )	return true;
366
	return false;
366
	return false;
367
}
367
}
368
 
368
 
369
unsigned char *CCatFile::readData ( SInCatFile *c, size_t *size )
369
unsigned char *CCatFile::readData(SInCatFile *c, size_t *size)
370
{
370
{
371
	*size = c->lSize;
371
	*size = c->lSize;
372
 
372
 
373
	if ( !c->sData ) {
373
	if ( !c->sData ) {
374
		if ( m_fDatFile.startRead() ) {
374
		if ( m_fDatFile.startRead() ) {
Line 398... Line 398...
398
{
398
{
399
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
399
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
400
		*pos^=0x33;
400
		*pos^=0x33;
401
	}
401
	}
402
}
402
}
403
unsigned char *CCatFile::readData ( CyString filename, size_t *size )
403
unsigned char *CCatFile::readData(const Utils::String &filename, size_t *size)
404
{
404
{
405
	*size = 0;
405
	*size = 0;
406
 
406
 
407
	if ( !m_fDatFile.NoFile() ) {
407
	if ( !m_fDatFile.NoFile() ) {
408
		SInCatFile *c = FindData ( filename );
408
		SInCatFile *c = findData(filename);
409
		if ( c ) return readData ( c, size );
409
		if ( c ) return readData ( c, size );
410
	}
410
	}
411
 
411
 
412
	return NULL;
412
	return NULL;
413
}
413
}
Line 573... Line 573...
573
		return fo.changeFileExtension("pbd");
573
		return fo.changeFileExtension("pbd");
574
 
574
 
575
	return f;
575
	return f;
576
}
576
}
577
 
577
 
578
bool CCatFile::AppendFile(const Utils::String &filename, const Utils::String &sTo, bool pck, bool bXor, Utils::String *sChangeTo)
578
bool CCatFile::appendFile(const Utils::String &filename, const Utils::String &sTo, bool pck, bool bXor, Utils::String *sChangeTo)
579
{
579
{
580
	CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() Adding file, %s, into cat file, %s::%s [PCK:%s XOR:%s]", filename.c_str(), this->m_fCatFile.filename().c_str(), sTo.c_str(), (pck) ? "Yes" : "No", (bXor) ? "Yes" : "No");
580
	CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() Adding file, %s, into cat file, %s::%s [PCK:%s XOR:%s]", filename.c_str(), this->m_fCatFile.filename().c_str(), sTo.c_str(), (pck) ? "Yes" : "No", (bXor) ? "Yes" : "No");
581
 
581
 
582
	if ( filename.isin ( "::" ) ) return WriteFromCat ( filename.token("::", 1), filename.token("::", 2));
582
	if ( filename.isin ( "::" ) ) return writeFromCat(filename.token("::", 1), filename.token("::", 2));
583
	if ( (!m_bCreate) && (!m_fDatFile.exists ()) ) {
583
	if ( (!m_bCreate) && (!m_fDatFile.exists ()) ) {
584
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Cat File: %s, doesn't exist, quitting...", m_fCatFile.fullFilename().c_str());
584
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Cat File: %s, doesn't exist, quitting...", m_fCatFile.fullFilename().c_str());
585
		return false;
585
		return false;
586
	}
586
	}
587
	Utils::String to = sTo;
587
	Utils::String to = sTo;
Line 596... Line 596...
596
		to = PckChangeExtension(to);
596
		to = PckChangeExtension(to);
597
	}
597
	}
598
	if ( sChangeTo ) *sChangeTo = to;
598
	if ( sChangeTo ) *sChangeTo = to;
599
 
599
 
600
	if ( !_lFiles->empty() ) {
600
	if ( !_lFiles->empty() ) {
601
		SInCatFile *checkf = FindData ( to );
601
		SInCatFile *checkf = findData(to);
602
		if ( checkf ) {
602
		if ( checkf ) {
603
			CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() removing existing filechanging file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).c_str());
603
			CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() removing existing filechanging file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).c_str());
604
			if ( !removeFile(checkf) ) {
604
			if ( !removeFile(checkf) ) {
605
				CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() unable to remove existing file, quitting...");
605
				CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() unable to remove existing file, quitting...");
606
				return false;
606
				return false;
Line 677... Line 677...
677
	CLog::logf(CLog::Log_IO, 4, "CCatFile::AppendFile() function complete");
677
	CLog::logf(CLog::Log_IO, 4, "CCatFile::AppendFile() function complete");
678
 
678
 
679
	return append;
679
	return append;
680
}
680
}
681
 
681
 
682
bool CCatFile::AddData ( CyString catfile, unsigned char *data, size_t size, CyString to, bool pck, bool create )
682
bool CCatFile::addData(const Utils::String &catfile, unsigned char *data, size_t size, const Utils::String &to, bool pck, bool create)
683
{
683
{
684
	int err = open(catfile.ToString(), "", CATREAD_CATDECRYPT, create);
684
	int err = open(catfile, "", CATREAD_CATDECRYPT, create);
685
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
685
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
686
		return false;
686
		return false;
687
 
687
 
688
	return AppendData ( data, size, to, pck );
688
	return appendData(data, size, to, pck);
689
}
689
}
690
 
690
 
691
int CCatFile::GetEndOffset()
691
int CCatFile::GetEndOffset()
692
{
692
{
693
	if ( _lFiles->empty() )
693
	if ( _lFiles->empty() )
Line 705... Line 705...
705
SInCatFile *CCatFile::GetFile(unsigned int num) const 
705
SInCatFile *CCatFile::GetFile(unsigned int num) const 
706
{ 
706
{ 
707
	return (num >= 0 && num < _lFiles->size()) ? _lFiles->at(num) : NULL; 
707
	return (num >= 0 && num < _lFiles->size()) ? _lFiles->at(num) : NULL; 
708
}
708
}
709
 
709
 
710
bool CCatFile::AppendData ( unsigned char *data, size_t size, CyString sTo, bool pck, bool bXor )
710
bool CCatFile::appendData(unsigned char *data, size_t size, const Utils::String &aTo, bool pck, bool bXor)
711
{
711
{
712
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) )
712
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) )
713
		return false;
713
		return false;
714
 
714
 
715
	if ( (size <= 0) || (!data) )
715
	if ( (size <= 0) || (!data) )
716
		return false;
716
		return false;
717
 
717
 
718
	Utils::String to = sTo.ToString();
718
	Utils::String to = aTo;
719
 
719
 
720
	// then check if the file already exists
720
	// then check if the file already exists
721
	if ( !_lFiles->empty() )
721
	if ( !_lFiles->empty() )
722
	{
722
	{
723
		SInCatFile *f = FindData ( to );
723
		SInCatFile *f = findData(to);
724
		if ( f )
724
		if ( f )
725
		{
725
		{
726
			if (!removeFile ( f ))
726
			if (!removeFile ( f ))
727
				return false;
727
				return false;
728
		}
728
		}
Line 747... Line 747...
747
	{
747
	{
748
		to = PckChangeExtension ( to );
748
		to = PckChangeExtension ( to );
749
 
749
 
750
		if (!_lFiles->empty())
750
		if (!_lFiles->empty())
751
		{
751
		{
752
			SInCatFile *f = FindData ( to );
752
			SInCatFile *f = findData(to);
753
			if ( f )
753
			if ( f )
754
			{
754
			{
755
				if (!removeFile(f))
755
				if (!removeFile(f))
756
					return false;
756
					return false;
757
			}
757
			}
Line 802... Line 802...
802
	else if ( ext == "pbd" )
802
	else if ( ext == "pbd" )
803
		return fo.changeFileExtension ( "bod" );
803
		return fo.changeFileExtension ( "bod" );
804
	return f->sFile;
804
	return f->sFile;
805
}
805
}
806
 
806
 
807
void CCatFile::FindFiles(CyStringList *files, CyString filemask)
807
void CCatFile::findFiles(Utils::CStringList &files, const Utils::String &filemask) const
808
{
808
{
809
	if (_lFiles->empty())
809
	if (_lFiles->empty())
810
		return;
810
		return;
811
 
811
 
812
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
812
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
813
	{
813
	{
814
		if ( filemask.WildMatch((*itr)->sFile) )
814
		if (filemask.match((*itr)->sFile))
815
			files->PushBack(CyString((*itr)->sFile));
815
			files.pushBack((*itr)->sFile);
816
	}
816
	}
817
}
817
}
818
 
818
 
819
bool CCatFile::ExtractAll(CyString dir)
819
bool CCatFile::extractAll(const Utils::String &dir)
820
{
820
{
821
	if (_lFiles->empty())
821
	if (_lFiles->empty())
822
		return false;
822
		return false;
823
 
823
 
824
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
824
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
825
	{
825
	{
826
		if ( !ExtractFile(*itr, dir, true) )
826
		if ( !extractFile(*itr, dir, true) )
827
			return false;
827
			return false;
828
	}
828
	}
829
 
829
 
830
	return true;
830
	return true;
831
}
831
}
832
bool CCatFile::ExtractFile ( CyString filename, CyString to, bool preserve )
832
bool CCatFile::extractFile(const Utils::String &filename, const Utils::String &to, bool preserve)
833
{
833
{
834
	if (_lFiles->empty())
834
	if (_lFiles->empty())
835
		return false;
835
		return false;
836
 
836
 
837
	// check if file exists
837
	// check if file exists
838
	if ( !_sAddonDir.empty() ) {
838
	if ( !_sAddonDir.empty() ) {
839
		SInCatFile *f = FindData ( CyString(_sAddonDir) + "\\" + filename );
839
		SInCatFile *f = findData(_sAddonDir + "\\" + filename);
840
		if ( f )
840
		if ( f )
841
			return ExtractFile ( f, to, preserve );
841
			return extractFile(f, to, preserve);
842
	}
842
	}
843
	{
843
	{
844
		SInCatFile *f = FindData ( CyString(";addon\\") + filename );
844
		SInCatFile *f = findData(";addon\\" + filename);
845
		if ( f )
845
		if ( f )
846
			return ExtractFile ( f, to, preserve );
846
			return extractFile(f, to, preserve);
847
	}
847
	}
848
 
848
 
849
	SInCatFile *f = FindData ( filename );
849
	SInCatFile *f = findData(filename);
850
	if ( !f )
850
	if ( !f )
851
	{
851
	{
852
		m_iError = CATERR_NOFILE;
852
		m_iError = CATERR_NOFILE;
853
		return false;
853
		return false;
854
	}
854
	}
855
 
855
 
856
	return ExtractFile ( f, to, preserve );
856
	return extractFile(f, to, preserve);
857
}
857
}
858
 
858
 
859
int CCatFile::_checkFiletype(const unsigned char *pBuffer, int iSize)
859
int CCatFile::_checkFiletype(const unsigned char *pBuffer, int iSize)
860
{
860
{
861
	if(iSize >= 3) {
861
	if(iSize >= 3) {
Line 870... Line 870...
870
	}	
870
	}	
871
 
871
 
872
	return FILETYPE_PLAIN;
872
	return FILETYPE_PLAIN;
873
}
873
}
874
 
874
 
875
bool CCatFile::ExtractFile ( SInCatFile *f, CyString to, bool preserve )
875
bool CCatFile::extractFile(SInCatFile* f, const Utils::String &to, bool preserve)
876
{
876
{
877
	unsigned char *data = 0;
877
	unsigned char *data = 0;
878
	size_t size = 0;
878
	size_t size = 0;
879
 
879
 
880
	// load the data from file
880
	// load the data from file
881
	ReadFileToData ( f );
881
	readFileToData(f);
882
 
882
 
883
	data = this->UnpackFile(f, &size);
883
	data = this->UnpackFile(f, &size);
884
	if ( !data ) {
884
	if ( !data ) {
885
		m_iError = CATERR_CANTREAD;
885
		m_iError = CATERR_CANTREAD;
886
		return false;
886
		return false;
887
	}
887
	}
888
 
888
 
889
	CFileIO fo(CCatFile::RenameFileExtension(f));
889
	CFileIO fo(CCatFile::RenameFileExtension(f));
890
	// check for a file name
890
	// check for a file name
891
	CyString checkFile = to;
891
	Utils::String checkFile = to;
892
	CyString todir, tofile = to;
892
	Utils::String todir, tofile = to;
893
	if ( checkFile.IsAnyIn("\\/") )
893
	if ( checkFile.containsAny("\\/") )
894
	{
894
	{
895
		checkFile = checkFile.FindReplace ( "\\", "/" );
895
		checkFile = checkFile.findReplace ( "\\", "/" );
896
		checkFile = checkFile.FindReplace ( "//", "/" );
896
		checkFile = checkFile.findReplace ( "//", "/" );
897
		tofile = checkFile.GetToken("/", checkFile.NumToken(&apos;/&apos;));
897
		tofile = checkFile.token("/", checkFile.countToken(&quot;/&quot;));
898
 
898
 
899
		if ( !checkFile.IsIn(".") || preserve )
899
		if ( !checkFile.contains(".") || preserve )
900
		{
900
		{
901
			tofile = fo.filename();
901
			tofile = fo.filename();
902
			todir = checkFile;
902
			todir = checkFile;
903
		}
903
		}
904
		else
904
		else
Line 906... Line 906...
906
			todir = CFileIO(checkFile).dir();
906
			todir = CFileIO(checkFile).dir();
907
			tofile = CFileIO(checkFile).filename();
907
			tofile = CFileIO(checkFile).filename();
908
		}
908
		}
909
	}
909
	}
910
 
910
 
911
	if ( tofile.Empty() )
911
	if ( tofile.empty() )
912
	{
912
	{
913
		if ( !tofile.Empty() )
913
		if ( !tofile.empty() )
914
			tofile += "/";
914
			tofile += "/";
915
		tofile += fo.filename();
915
		tofile += fo.filename();
916
		todir = CFileIO(tofile).dir();
916
		todir = CFileIO(tofile).dir();
917
		tofile = CFileIO(tofile).filename();
917
		tofile = CFileIO(tofile).filename();
918
	}
918
	}
919
	
919
	
920
	if ( preserve )
920
	if ( preserve )
921
	{
921
	{
922
		if ( !fo.dir().Compare(todir.Right(- (int)fo.dir().length()).ToString()) )
922
		if ( !fo.dir().Compare(todir.right(- (int)fo.dir().length())) )
923
		{
923
		{
924
			if ( !todir.Empty() && todir.Right(1) != "/" )
924
			if ( !todir.empty() && todir.right(1) != "/" )
925
				todir += "/";
925
				todir += "/";
926
			todir += fo.dir();
926
			todir += fo.dir();
927
		}
927
		}
928
	}
928
	}
929
 
929
 
930
	if ( tofile.Empty() )
930
	if ( tofile.empty() )
931
		tofile = fo.filename();
931
		tofile = fo.filename();
932
 
932
 
933
	bool bWritten = false;
933
	bool bWritten = false;
934
 
934
 
935
	// create the directory to extract to
935
	// create the directory to extract to
936
	if ( !todir.Empty() && !CDirIO(todir).create() )
936
	if ( !todir.empty() && !CDirIO(todir).create() )
937
		m_iError = CATERR_CANTCREATEDIR;
937
		m_iError = CATERR_CANTCREATEDIR;
938
	else
938
	else
939
	{
939
	{
940
		CyString file = todir;
940
		Utils::String file = todir;
941
		if ( !file.Empty() )
941
		if ( !file.empty() )
942
			file += "/";
942
			file += "/";
943
		file += tofile;
943
		file += tofile;
944
		file = file.FindReplace("/", "\\");
944
		file = file.findReplace("/", "\\");
945
		file = file.FindReplace("\\\\", "\\");
945
		file = file.findReplace("\\\\", "\\");
946
 
946
 
947
		CFileIO File(file.c_str());
947
		CFileIO File(file.c_str());
948
		if ( !File.startWrite() ) m_iError = CATERR_INVALIDDEST;
948
		if ( !File.startWrite() ) m_iError = CATERR_INVALIDDEST;
949
		else bWritten = File.write(data, size);
949
		else bWritten = File.write(data, size);
950
	}
950
	}
Line 1109... Line 1109...
1109
	}
1109
	}
1110
 
1110
 
1111
	return NULL;
1111
	return NULL;
1112
}
1112
}
1113
 
1113
 
1114
bool CCatFile::WriteFromCat ( CCatFile *fcat, CyString file )
1114
bool CCatFile::writeFromCat(CCatFile *fcat, const Utils::String &file)
1115
{
1115
{
1116
	// now find the file in the cat file
1116
	// now find the file in the cat file
1117
	SInCatFile *getfile = fcat->FindData ( file );
1117
	SInCatFile *getfile = fcat->findData(file);
1118
	if ( !getfile )
1118
	if ( !getfile )
1119
		return false;
1119
		return false;
1120
 
1120
 
1121
	// read the dat from the cat file
1121
	// read the dat from the cat file
1122
	size_t size = 0;
1122
	size_t size = 0;
1123
	unsigned char *data = fcat->readData ( getfile, &size );
1123
	unsigned char *data = fcat->readData ( getfile, &size );
1124
	if ( !data )
1124
	if ( !data )
1125
		return false;
1125
		return false;
1126
 
1126
 
1127
	// now check if it exists in this file
1127
	// now check if it exists in this file
1128
	removeFile(file.ToString());
1128
	removeFile(file);
1129
 
1129
 
1130
	int offset = (_lFiles->empty()) ? 0 : (_lFiles->back()->lOffset + _lFiles->back()->lSize);
1130
	int offset = (_lFiles->empty()) ? 0 : (_lFiles->back()->lOffset + _lFiles->back()->lSize);
1131
	// now write to the new file
1131
	// now write to the new file
1132
	if ( getfile->bDecrypted ) this->DecryptDAT(getfile->sData, getfile->lSize);
1132
	if ( getfile->bDecrypted ) this->DecryptDAT(getfile->sData, getfile->lSize);
1133
	getfile->bDecrypted = false;
1133
	getfile->bDecrypted = false;
Line 1139... Line 1139...
1139
	f->sData = 0;
1139
	f->sData = 0;
1140
	if (_lFiles->empty())
1140
	if (_lFiles->empty())
1141
		f->lOffset = 0;
1141
		f->lOffset = 0;
1142
	else
1142
	else
1143
		f->lOffset = _lFiles->back()->lOffset + _lFiles->back()->lSize;
1143
		f->lOffset = _lFiles->back()->lOffset + _lFiles->back()->lSize;
1144
	f->sFile = file.ToString();
1144
	f->sFile = file;
1145
	f->lSize = size;
1145
	f->lSize = size;
1146
	_lFiles->push_back(f);
1146
	_lFiles->push_back(f);
1147
	m_bCatChanged = true;
1147
	m_bCatChanged = true;
1148
 
1148
 
1149
	return true;
1149
	return true;
1150
}
1150
}
1151
 
1151
 
1152
bool CCatFile::WriteFromCat ( CyString catfile, CyString file )
1152
bool CCatFile::writeFromCat(const Utils::String &catfile, const Utils::String &file)
1153
{
1153
{
1154
	CCatFile fcat;
1154
	CCatFile fcat;
1155
	if ( fcat.open(catfile.ToString(), "", CATREAD_CATDECRYPT, false) )
1155
	if ( fcat.open(catfile, "", CATREAD_CATDECRYPT, false) )
1156
		return false;
1156
		return false;
1157
 
1157
 
1158
	return this->WriteFromCat(&fcat, file);
1158
	return this->writeFromCat(&fcat, file);
1159
}
1159
}
1160
 
-
 
1161
SInCatFile *CCatFile::FindData(CyString filename)
-
 
1162
{
-
 
1163
	return findData(filename.ToString());
-
 
1164
}
-
 
1165
 
-
 
1166
SInCatFile *CCatFile::findData(const Utils::String &filename) const
1160
SInCatFile *CCatFile::findData(const Utils::String &filename) const
1167
{
1161
{
1168
	if (_lFiles->empty())
1162
	if (_lFiles->empty())
1169
		return NULL;
1163
		return NULL;
1170
 
1164
 
Line 1178... Line 1172...
1178
			return *itr;
1172
			return *itr;
1179
	}
1173
	}
1180
	return NULL;
1174
	return NULL;
1181
}
1175
}
1182
 
1176
 
1183
bool CCatFile::MarkRemoveFile( CyString file )
1177
bool CCatFile::markRemoveFile(const Utils::String &file)
1184
{
1178
{
1185
	SInCatFile *f = FindData ( file );
1179
	SInCatFile *f = findData(file);
1186
	if ( !f )
1180
	if ( !f )
1187
	{
1181
	{
1188
		m_iError = CATERR_NOFILE;
1182
		m_iError = CATERR_NOFILE;
1189
		return false;
1183
		return false;
1190
	}
1184
	}
1191
 
1185
 
1192
	return MarkRemoveFile ( f );
1186
	return markRemoveFile(f);
1193
}
1187
}
1194
bool CCatFile::MarkRemoveFile ( SInCatFile *f )
1188
bool CCatFile::markRemoveFile ( SInCatFile *f )
1195
{
1189
{
1196
	f->bDelete = true;
1190
	f->bDelete = true;
1197
	return true;
1191
	return true;
1198
}
1192
}