imgtools/romtools/rofsbuild/r_obey.cpp
changeset 647 53d1ab72f5bc
parent 626 ac03b93ca9c4
child 654 7c11c3d8d025
equal deleted inserted replaced
641:8dd670a9f34f 647:53d1ab72f5bc
    38 #include "r_coreimage.h"
    38 #include "r_coreimage.h"
    39 #include "patchdataprocessor.h"
    39 #include "patchdataprocessor.h"
    40 #include "fatimagegenerator.h" 
    40 #include "fatimagegenerator.h" 
    41 #include "r_driveimage.h"
    41 #include "r_driveimage.h"
    42 
    42 
       
    43 #ifdef __LINUX__
       
    44 #include <dirent.h> 
       
    45 #include <sys/stat.h>
       
    46 #include <unistd.h>
       
    47 #else
       
    48 #include <io.h> 
       
    49 #include <direct.h> //TODO: check under MinGW4 + stlport 5.2
       
    50 #include <conio.h> 
       
    51 #endif
       
    52 
    43 #include "uniconv.hpp"
    53 #include "uniconv.hpp"
    44 extern TInt gCodePagingOverride;
    54 extern TInt gCodePagingOverride;
    45 extern TInt gDataPagingOverride;
    55 extern TInt gDataPagingOverride;
    46 extern ECompression gCompress;
    56 extern ECompression gCompress;
    47 extern TBool gEnableStdPathWarning; // Default to not warn if destination path provided for a file is not in standard path.
    57 extern TBool gEnableStdPathWarning; // Default to not warn if destination path provided for a file is not in standard path.
    55 const ObeyFileKeyword ObeyFileReader::iKeywords[] =
    65 const ObeyFileKeyword ObeyFileReader::iKeywords[] =
    56 {
    66 {
    57 	{_K("file"),		2,-2, EKeywordFile, "File to be copied into ROFS"},
    67 	{_K("file"),		2,-2, EKeywordFile, "File to be copied into ROFS"},
    58 	{_K("data"),		2,-2, EKeywordData, "same as file"},
    68 	{_K("data"),		2,-2, EKeywordData, "same as file"},
    59 	{_K("dir"),         2,1, EKeywordDir, "Directory to be created into FAT image"},
    69 	{_K("dir"),         2,1, EKeywordDir, "Directory to be created into FAT image"},
       
    70 	{_K("dircopy"),      2,-2, EKeywordDirCpy, "Directory to be copied into FAT image"},
    60 
    71 
    61 	{_K("rofsname"),	1, 1, EKeywordRofsName, "output file for ROFS image"},
    72 	{_K("rofsname"),	1, 1, EKeywordRofsName, "output file for ROFS image"},
    62 	{_K("romsize"),		1, 1, EKeywordRomSize, "size of ROM image"}, 
    73 	{_K("romsize"),		1, 1, EKeywordRomSize, "size of ROM image"}, 
    63 	{_P("hide"),	    2, -1, EKeywordHide, "Exclude named file from ROM directory structure"},
    74 	{_P("hide"),	    2, -1, EKeywordHide, "Exclude named file from ROM directory structure"},
    64 	{_P("alias"),	    2, -2, EKeywordAlias, "Create alias for existing file in ROM directory structure"},
    75 	{_P("alias"),	    2, -2, EKeywordAlias, "Create alias for existing file in ROM directory structure"},
   266 	iNumWords = Parse();
   277 	iNumWords = Parse();
   267 	return KErrNone;
   278 	return KErrNone;
   268 }
   279 }
   269 
   280 
   270 TInt ObeyFileReader::NextLine(TInt aPass, enum EKeyword& aKeyword) {
   281 TInt ObeyFileReader::NextLine(TInt aPass, enum EKeyword& aKeyword) {
   271 
   282 	static int warnline = -1;
   272 NextLine:
   283 NextLine:
   273 	TInt err = ReadAndParseLine();
   284 	TInt err = ReadAndParseLine();
   274 	if (err == KErrEof)
   285 	if (err == KErrEof)
   275 		return KErrEof;
   286 		return KErrEof;
   276 	if(iNumWords == 0)
   287 	if(iNumWords == 0)
   310 		}
   321 		}
   311 
   322 
   312 		aKeyword = k->iKeywordEnum;
   323 		aKeyword = k->iKeywordEnum;
   313 		return KErrNone;
   324 		return KErrNone;
   314 	}
   325 	}
   315 	if (aPass == 1)
   326 	if (aPass == 1 && iCurrentLine > warnline){
       
   327 		warnline = iCurrentLine;
   316 		Print(EWarning, "Unknown keyword '%s'.  Line %d ignored\n", iWord[0], iCurrentLine);
   328 		Print(EWarning, "Unknown keyword '%s'.  Line %d ignored\n", iWord[0], iCurrentLine);
       
   329 	}
   317 	goto NextLine;
   330 	goto NextLine;
   318 }
   331 }
   319 
   332 
   320 //
   333 //
   321 // splits a line into words, and returns the number of words found
   334 // splits a line into words, and returns the number of words found
   738 			}
   751 			}
   739 
   752 
   740 		case EKeywordHide:						
   753 		case EKeywordHide:						
   741 		case EKeywordFile:
   754 		case EKeywordFile:
   742 		case EKeywordDir:
   755 		case EKeywordDir:
       
   756 		case EKeywordDirCpy:
   743 		case EKeywordData:
   757 		case EKeywordData:
   744 		case EKeywordFileCompress:
   758 		case EKeywordFileCompress:
   745 		case EKeywordFileUncompress:
   759 		case EKeywordFileUncompress:
   746 			if (!ProcessDriveFile(keyword))
   760 			if (!ProcessDriveFile(keyword))
   747 				return KErrGeneral;
   761 				return KErrGeneral;
   931 ETrue - Successful generation of tree.
   945 ETrue - Successful generation of tree.
   932 EFalse- Fail to generate the tree.
   946 EFalse- Fail to generate the tree.
   933 */
   947 */
   934 TBool CObeyFile::ProcessDriveFile(enum EKeyword aKeyword) {
   948 TBool CObeyFile::ProcessDriveFile(enum EKeyword aKeyword) {
   935 
   949 
   936 	TBool isPeFile = ETrue;
       
   937 	TBool aFileCompressOption, aFileUncompressOption;
   950 	TBool aFileCompressOption, aFileUncompressOption;
   938 
   951 
   939 	TInt epocPathStart=2;
   952 	TInt epocPathStart=2;
   940 	aFileCompressOption = aFileUncompressOption = EFalse;
   953 	aFileCompressOption = aFileUncompressOption = EFalse;
   941 	// do some validation of the keyword
   954 	// do some validation of the keyword
   943 
   956 
   944 	switch (aKeyword)
   957 	switch (aKeyword)
   945 	{
   958 	{
   946 	case EKeywordData:
   959 	case EKeywordData:
   947 	case EKeywordDir:
   960 	case EKeywordDir:
       
   961 	case EKeywordDirCpy:
   948 	case EKeywordHide:
   962 	case EKeywordHide:
   949 		isPeFile = EFalse;
       
   950 		break;
   963 		break;
   951 
   964 
   952 	case EKeywordFile:
   965 	case EKeywordFile:
   953 		break;
   966 		break;
   954 
   967 
   962 
   975 
   963 	default:
   976 	default:
   964 		return EFalse;
   977 		return EFalse;
   965 	}
   978 	}
   966 
   979 
   967 	if (aKeyword!=EKeywordHide && aKeyword!=EKeywordDir) {
   980 	if (aKeyword!=EKeywordHide && aKeyword!=EKeywordDir && aKeyword!=EKeywordDirCpy) {
   968 		// check the PC file exists
   981 		// check the PC file exists
   969 		char* nname = NormaliseFileName(iReader.Word(1));		  
   982 		char* nname = NormaliseFileName(iReader.Word(1));		  
   970 		if(gIsOBYUTF8 && !UniConv::IsPureASCIITextStream(nname))
   983 		if(gIsOBYUTF8 && !UniConv::IsPureASCIITextStream(nname))
   971 		{
   984 		{
   972 			char* tempnname = strdup(nname);
   985 			char* tempnname = strdup(nname);
   988 		}
  1001 		}
   989 		test.close();
  1002 		test.close();
   990 		delete []nname ;												
  1003 		delete []nname ;												
   991 		 
  1004 		 
   992 	}
  1005 	}
   993 	else
  1006 	else if (aKeyword != EKeywordDirCpy)
   994 		epocPathStart=1;   
  1007 		epocPathStart=1;   
   995 
       
   996 	if(aKeyword != EKeywordDir)
       
   997 		iNumberOfFiles++;
       
   998 
  1008 
   999 	TBool endOfName=EFalse;
  1009 	TBool endOfName=EFalse;
  1000 	const char *epocStartPtr;
  1010 	const char *epocStartPtr;
  1001 	if(aKeyword != EKeywordDir)
  1011 	if(aKeyword != EKeywordDir && aKeyword != EKeywordDirCpy)
  1002 		epocStartPtr = IsValidFilePath(iReader.Word(epocPathStart));
  1012 		epocStartPtr = IsValidFilePath(iReader.Word(epocPathStart));
  1003 	else
  1013 	else
  1004 		epocStartPtr = IsValidDirPath(iReader.Word(epocPathStart));
  1014 		epocStartPtr = IsValidDirPath(iReader.Word(epocPathStart));
  1005 	char *epocEndPtr = const_cast<char*>(epocStartPtr);
  1015 	char *epocEndPtr = const_cast<char*>(epocStartPtr);
  1006 
  1016 
  1009 		return EFalse;
  1019 		return EFalse;
  1010 	}
  1020 	}
  1011 
  1021 
  1012 	TRomNode* dir=iRootDirectory;
  1022 	TRomNode* dir=iRootDirectory;
  1013 	TRomNode* subDir=0;
  1023 	TRomNode* subDir=0;
  1014 	TRomBuilderEntry *file=0;      
       
  1015 
  1024 
  1016 	while (!endOfName) {
  1025 	while (!endOfName) {
  1017 		endOfName = GetNextBitOfFileName(epocEndPtr);      
  1026 		endOfName = GetNextBitOfFileName(epocEndPtr);      
  1018 		if (endOfName && (aKeyword!=EKeywordDir)) { // file
  1027 		if (endOfName && (aKeyword!=EKeywordDir) && (aKeyword!=EKeywordDirCpy)) { // file
  1019 			TRomNode* alreadyExists=dir->FindInDirectory(epocStartPtr);
  1028 			if (!AddFileToNodeTree(aKeyword, dir, epocStartPtr, iReader.Word(1), ETrue, aFileCompressOption, aFileUncompressOption))
  1020 			if ((aKeyword != EKeywordHide) && alreadyExists) { // duplicate file		
       
  1021 				if (gKeepGoing) {
       
  1022 					Print(EWarning, "Duplicate file for %s on line %d, will be ignored\n",iReader.Word(1),iReader.CurrentLine());
       
  1023 					iNumberOfFiles--;
       
  1024 					return ETrue;
       
  1025 				}
       
  1026 				else {	
       
  1027 					Print(EError, "Duplicate file for %s on line %d\n",iReader.Word(1),iReader.CurrentLine());
       
  1028 					return EFalse;
       
  1029 				}
       
  1030 			}
       
  1031 			else if((aKeyword == EKeywordHide) && (alreadyExists)) { 
       
  1032 				alreadyExists->iEntry->iHidden = ETrue;
       
  1033 				alreadyExists->iHidden = ETrue;
       
  1034 				return ETrue;
       
  1035 			}
       
  1036 			else if((aKeyword == EKeywordHide) && (!alreadyExists)) {
       
  1037 				Print(EWarning, "Hiding non-existent file %s on line %d\n",iReader.Word(1),iReader.CurrentLine());
       
  1038 				return ETrue;
       
  1039 			}
       
  1040 
       
  1041 			file = new TRomBuilderEntry(iReader.Word(1), epocStartPtr);                   
       
  1042 			file->iExecutable=isPeFile;
       
  1043 			if( aFileCompressOption ) {
       
  1044 				file->iCompressEnabled = ECompressionCompress;
       
  1045 			}
       
  1046 			else if(aFileUncompressOption )	{
       
  1047 				file->iCompressEnabled = ECompressionUncompress;
       
  1048 			}
       
  1049 
       
  1050 			TRomNode* node=new TRomNode(epocStartPtr, file);
       
  1051 			if (node==0)
       
  1052 				return EFalse;
  1029 				return EFalse;
  1053 
       
  1054 			TInt r=ParseFileAttributes(node, file, aKeyword);         
       
  1055 			if (r!=KErrNone)
       
  1056 				return EFalse;
       
  1057 
       
  1058 			if(gCompress != ECompressionUnknown) {
       
  1059 				node->iFileUpdate = ETrue;
       
  1060 			}
       
  1061 
       
  1062 			if((node->iOverride) || (aFileCompressOption) || (aFileUncompressOption)) {
       
  1063 				node->iFileUpdate = ETrue;
       
  1064 			}
       
  1065 
       
  1066 			dir->AddFile(node);	// to drive directory structure.
       
  1067 		}		 
  1030 		}		 
  1068 		else {
  1031 		else {
  1069 			// directory
  1032 			// directory
  1070 			//for directory creation, given /sys/bin/, it's possible to reach 0 at the end, just ignore that...
  1033 			//for directory creation, given /sys/bin/, it's possible to reach 0 at the end, just ignore that...
  1071 			if(!*epocStartPtr)
  1034 			if(!*epocStartPtr)
  1072 				break;
  1035 				break;
  1073 
  1036 
  1074 			subDir = dir->FindInDirectory(epocStartPtr);      
  1037 			subDir = AddDirToNodeTree(aKeyword, dir, epocStartPtr);				
  1075 			if (!subDir){ // sub directory does not exist			
  1038 			if (!subDir) {
  1076 				if(aKeyword==EKeywordHide) {
  1039 				if (aKeyword != EKeywordHide)
  1077 					Print(EWarning, "Hiding non-existent file %s on line %d\n",
  1040 					return EFalse;//this is for memory alloc failed
  1078 						iReader.Word(1),iReader.CurrentLine());
  1041 				else
  1079 					return ETrue;
  1042 					return ETrue;//this is for hide a non-exist dir
  1080 				}
       
  1081 				subDir = dir->NewSubDir(epocStartPtr);
       
  1082 				if (!subDir)
       
  1083 					return EFalse;
       
  1084 			}
  1043 			}
  1085 			dir=subDir;
  1044 			dir=subDir;
  1086 			epocStartPtr = epocEndPtr;
  1045 			epocStartPtr = epocEndPtr;
  1087 		}  // end of else.
  1046 		}  // end of else.
  1088 	}
  1047 	}
       
  1048 
       
  1049 	if (aKeyword == EKeywordDirCpy)	{
       
  1050 		if(!CreateFromFolder(iReader.Word(1), dir))
       
  1051 			return EFalse;
       
  1052 	}
       
  1053 		
  1089 	return ETrue;
  1054 	return ETrue;
  1090 }
  1055 }
  1091 
  1056 
       
  1057 TRomNode* CObeyFile::AddFileToNodeTree(enum EKeyword aKeyword, TRomNode* dir, const char* filename, const char* aPCSidename, const TBool aParseAttr, TBool aFileCompressOption, TBool aFileUncompressOption)	{
       
  1058 	TRomNode* alreadyExists=dir->FindInDirectory(filename);
       
  1059 	if ((aKeyword != EKeywordHide) && alreadyExists) { // duplicate file		
       
  1060 		if (gKeepGoing) {
       
  1061 			Print(EWarning, "Duplicate file for %s on line %d, will be ignored\n",aPCSidename,iReader.CurrentLine());
       
  1062 			return alreadyExists;
       
  1063 		}
       
  1064 		else {	
       
  1065 			Print(EError, "Duplicate file for %s on line %d\n",aPCSidename,iReader.CurrentLine());
       
  1066 			return 0;
       
  1067 		}
       
  1068 	}
       
  1069 	else if((aKeyword == EKeywordHide) && (alreadyExists)) { 
       
  1070 		alreadyExists->iEntry->iHidden = ETrue;
       
  1071 		alreadyExists->iHidden = ETrue;
       
  1072 		return alreadyExists;
       
  1073 	}
       
  1074 	else if((aKeyword == EKeywordHide) && (!alreadyExists)) {
       
  1075 		Print(EWarning, "Hiding non-existent file %s on line %d\n",aPCSidename,iReader.CurrentLine());
       
  1076 		return (TRomNode*)1;
       
  1077 	}
       
  1078 
       
  1079 	iNumberOfFiles++;
       
  1080 	TRomBuilderEntry* file = new TRomBuilderEntry(aPCSidename, filename);                   
       
  1081 	if( aFileCompressOption ) {
       
  1082 		file->iCompressEnabled = ECompressionCompress;
       
  1083 	}
       
  1084 	else if(aFileUncompressOption )	{
       
  1085 		file->iCompressEnabled = ECompressionUncompress;
       
  1086 	}
       
  1087 
       
  1088 	TRomNode* node=new TRomNode(filename, file);
       
  1089 	if (node==0)
       
  1090 		return 0;
       
  1091 
       
  1092 	if (aParseAttr){
       
  1093 		TInt r=ParseFileAttributes(node, file, aKeyword);         
       
  1094 		if (r!=KErrNone)
       
  1095 			return 0;
       
  1096 	}
       
  1097 	if(gCompress != ECompressionUnknown) {
       
  1098 		node->iFileUpdate = ETrue;
       
  1099 	}
       
  1100 
       
  1101 	if((node->iOverride) || (aFileCompressOption) || (aFileUncompressOption)) {
       
  1102 		node->iFileUpdate = ETrue;
       
  1103 	}
       
  1104 
       
  1105 	dir->AddFile(node);	// to drive directory structure.
       
  1106 	return node;
       
  1107 }
       
  1108 
       
  1109 TRomNode* CObeyFile::AddDirToNodeTree(enum EKeyword aKeyword, TRomNode* dir, const char* dirname) {
       
  1110 	TRomNode* subDir = dir->FindInDirectory(dirname);      
       
  1111 	if (!subDir){ // sub directory does not exist			
       
  1112 		if(aKeyword==EKeywordHide) {
       
  1113 			Print(EWarning, "Hiding non-existent file %s on line %d\n",
       
  1114 				iReader.Word(1),iReader.CurrentLine());
       
  1115 			return 0;
       
  1116 		}
       
  1117 		subDir = dir->NewSubDir(dirname);
       
  1118 		if (!subDir)
       
  1119 			return 0;
       
  1120 	}
       
  1121 	return subDir;
       
  1122 }
       
  1123 
       
  1124 TBool CObeyFile::CreateFromFolder(const char* aPath,TRomNode* aParent) { 
       
  1125 	int len = strlen(aPath);  
       
  1126 	if(!aParent)
       
  1127 		aParent = new TRomNode("//");
       
  1128 #ifdef __LINUX__
       
  1129 	DIR* dir = opendir(aPath);
       
  1130 	if(dir == NULL) {
       
  1131 		Print(EError, "The directory %s does not exist.\n",aPath);
       
  1132 		return EFalse;
       
  1133 	}
       
  1134 	dirent*  entry; 
       
  1135 	struct stat statbuf ;
       
  1136 	char* fileName = new(nothrow) char[len + 200];
       
  1137 	if(!fileName) return EFalse ;
       
  1138 	memcpy(fileName,aPath,len); 
       
  1139 	fileName[len] = '/';
       
  1140 	while ((entry = readdir(dir)) != NULL)  {
       
  1141 		if(strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0)
       
  1142 			continue ; 
       
  1143 		strcpy(&fileName[len+1],entry->d_name);             
       
  1144 		stat(fileName , &statbuf);   
       
  1145 		if (S_ISDIR(statbuf.st_mode)){
       
  1146 			TRomNode* subdir = AddDirToNodeTree(EKeywordDirCpy, aParent, entry->d_name);
       
  1147 			if (!subdir){
       
  1148 				delete []fileName;
       
  1149 				return EFalse;
       
  1150 			}
       
  1151 			if (!CreateFromFolder(fileName, subdir)){
       
  1152 				delete []fileName;
       
  1153 				return EFalse;
       
  1154 			}
       
  1155 		}else{
       
  1156 			if (!AddFileToNodeTree(EKeywordDirCpy, aParent, entry->d_name, fileName, EFalse)){
       
  1157 				delete []fileName;
       
  1158 				return EFalse;
       
  1159 			}
       
  1160 		}
       
  1161 	}	
       
  1162 	delete []fileName ;
       
  1163 	closedir(dir);
       
  1164 #else
       
  1165 	struct _finddata_t data ;
       
  1166 	memset(&data, 0, sizeof(data)); 	
       
  1167 	char* fileName = new(nothrow) char[len + 200];
       
  1168 	if(!fileName) return EFalse ;
       
  1169 	memcpy(fileName,aPath,len); 
       
  1170   fileName[len] = '\\';
       
  1171 	fileName[len+1] = '*';
       
  1172 	fileName[len+2] = 0;
       
  1173 	intptr_t hFind =  _findfirst(fileName,&data); 
       
  1174  
       
  1175 	if(hFind == (intptr_t)-1 ) {
       
  1176 		Print(EError, "The directory %s does not exist.\n",aPath);
       
  1177 		delete []fileName;
       
  1178 		return EFalse;
       
  1179 	}	
       
  1180 	
       
  1181 	do {        
       
  1182     if(strcmp(data.name,".") == 0 || strcmp(data.name,"..") == 0)
       
  1183         continue ; 
       
  1184         
       
  1185     strcpy(&fileName[len+1],data.name); 
       
  1186     if(data.attrib & _A_SUBDIR){ 
       
  1187 			TRomNode* subDir = AddDirToNodeTree(EKeywordDirCpy, aParent, data.name);
       
  1188 			if (!subDir){
       
  1189 				delete []fileName;
       
  1190 				return EFalse;
       
  1191 			}
       
  1192       if(data.attrib & _A_RDONLY)
       
  1193 				subDir->iAtt |= KEntryAttReadOnly;
       
  1194       if(data.attrib &  _A_HIDDEN){
       
  1195 				subDir->iAtt |= KEntryAttHidden;
       
  1196 			}
       
  1197       if(data.attrib & _A_SYSTEM)
       
  1198 				subDir->iAtt |= KEntryAttSystem;
       
  1199 			if (!CreateFromFolder(fileName, subDir)){
       
  1200 				delete []fileName;
       
  1201 				return EFalse;
       
  1202 			}
       
  1203 		}else{
       
  1204 			TRomNode* node = AddFileToNodeTree(EKeywordDirCpy, aParent, data.name, fileName, EFalse);
       
  1205 			if (!node){
       
  1206 				delete []fileName;
       
  1207 				return EFalse;
       
  1208 			}
       
  1209       if(data.attrib & _A_RDONLY)
       
  1210 				node->iAtt |= KEntryAttReadOnly;
       
  1211       if(data.attrib &  _A_HIDDEN){
       
  1212 				node->iAtt |= KEntryAttHidden;
       
  1213      		node->iEntry->iHidden = ETrue;
       
  1214 				node->iHidden = ETrue;
       
  1215 			}
       
  1216       if(data.attrib & _A_SYSTEM)
       
  1217 				node->iAtt |= KEntryAttSystem;
       
  1218 		}
       
  1219   } while(-1 != _findnext(hFind, &data));
       
  1220 	delete []fileName ;
       
  1221   _findclose(hFind);
       
  1222 #endif
       
  1223  
       
  1224 	return ETrue;
       
  1225 }
  1092 
  1226 
  1093 TInt CObeyFile::SetStackSize(TRomNode *aNode, const char* aStr) {
  1227 TInt CObeyFile::SetStackSize(TRomNode *aNode, const char* aStr) {
  1094 	if (EFalse == IsValidNumber(aStr))
  1228 	if (EFalse == IsValidNumber(aStr))
  1095 		return Print(EError, "Number required as argument for keyword 'stack'.\n"); 
  1229 		return Print(EError, "Number required as argument for keyword 'stack'.\n"); 
  1096 	TInt size ;
  1230 	TInt size ;