imgtools/romtools/rofsbuild/r_driveimage.cpp
changeset 0 044383f39525
child 590 360bd6b35136
child 606 30b30f9da0b7
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 /*
       
     2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * @internalComponent * @released
       
    16 * Driveimage class implementation.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #include <stdlib.h>
       
    22 #include <string>
       
    23 
       
    24 #ifndef __LINUX__
       
    25 	#include <windows.h>
       
    26 	#include <direct.h>
       
    27 #else
       
    28 	#include <dirent.h>
       
    29 #endif
       
    30 
       
    31 #ifdef __TOOLS2__
       
    32 	#include <sys/stat.h>
       
    33 	#include <sys/types.h>
       
    34 	using namespace std;
       
    35 #endif
       
    36 
       
    37 #include <f32file.h>
       
    38 #include "h_utl.h"
       
    39 #include "r_obey.h"
       
    40 #include "r_romnode.h"
       
    41 #include "r_rofs.h"
       
    42 #include "r_driveimage.h"
       
    43 
       
    44 extern TBool gFastCompress;
       
    45 
       
    46 // File format supported by Rofsbuild
       
    47 DriveFileFormatSupported CDriveImage::iFormatType[] =
       
    48 	{
       
    49 		{"FAT16",EFAT16},
       
    50 		{"FAT32",EFAT32},
       
    51 		{0,EFATINVALID}
       
    52 	};
       
    53 
       
    54 
       
    55 /**
       
    56 File format conversion from char* to coresponding enum value.
       
    57 
       
    58 @param aUserFileFormat - pointer to user entered file format.
       
    59 @param aDriveFileFormat - Reference to actual variable.
       
    60 */
       
    61 TBool CDriveImage::FormatTranslation(TText* aUserFileFormat,enum TFileSystem& aDriveFileFormat)
       
    62 	{
       
    63 	struct DriveFileFormatSupported* strPointer = iFormatType;
       
    64 	for( ; (strPointer->iDriveFileFormat) != '\0' ; ++strPointer )
       
    65 		{
       
    66 		if(!strcmp((char*)aUserFileFormat,strPointer->iDriveFileFormat))
       
    67 			{
       
    68 			aDriveFileFormat = strPointer->iFileSystem;
       
    69 			return ETrue;
       
    70 			}
       
    71 		}	
       
    72 	return EFalse;
       
    73 	}
       
    74 
       
    75 
       
    76 /**
       
    77 Constructor: CDriveImage class 
       
    78 
       
    79 @param aObey - pointer to Drive obey file.
       
    80 */
       
    81 CDriveImage::CDriveImage(CObeyFile *aObey)
       
    82 	: iObey( aObey ),iParentInnerList(0),iListReference(0),iTempDirName(NULL), iData(0)
       
    83 	{
       
    84 	}
       
    85 
       
    86 
       
    87 /**
       
    88 Destructor: CDriveImage class 
       
    89 
       
    90 Release the resources allocated in heap.
       
    91 */
       
    92 CDriveImage::~CDriveImage()
       
    93 	{
       
    94 	iNodeAddStore.clear();
       
    95 	iNodeList.clear();
       
    96 	if(iData)
       
    97 		delete[] iData;
       
    98 	if(iTempDirName)
       
    99 		delete[] iTempDirName;
       
   100 	}
       
   101 
       
   102 
       
   103 /**
       
   104 Creates the STL list to interface with file system module.
       
   105 Creates the Temp folder for placing the executables
       
   106    (those changed,due to user option like compression,un-compression & fileattribute)
       
   107 Updates the excutable options (file attributes, compression etc)
       
   108 
       
   109 @return Status - 'KErrNone' - successfully done above operations.
       
   110                  'KErrNoMemory' - Not able to allocate the memory.
       
   111 				 'KErrGeneral' - Unable to done the above operations.
       
   112 */
       
   113 TInt CDriveImage::CreateList()
       
   114 	{
       
   115 
       
   116 	TRomNode* pRootDir = iObey->iRootDirectory;
       
   117 	TInt16 dirCheck = 1;
       
   118 	TInt retStatus = 0;
       
   119 
       
   120 	// For Creating the temp folder.	
       
   121 	iTempDirName = new char[KMaxGenBuffer];
       
   122 	if(!iTempDirName)
       
   123 		return KErrNoMemory;
       
   124 
       
   125 	// Create the temp folder.
       
   126 	// Check for folder exist, if exist it loops until dir created or loop exit.
       
   127 	while(dirCheck)
       
   128 		{
       
   129 		sprintf(iTempDirName,"%s%05d","temp",dirCheck);
       
   130 #ifdef __LINUX__
       
   131 		retStatus = mkdir((char*)iTempDirName,0777);
       
   132 #else
       
   133 		retStatus = mkdir((char*)iTempDirName);
       
   134 #endif
       
   135 		if(!retStatus)
       
   136 			break;	
       
   137 
       
   138 		++dirCheck;
       
   139 		}
       
   140 
       
   141 	if(!dirCheck)
       
   142 		{
       
   143 		Print(EError,"Unable to Create the temp folder,Check directory settings.\n");
       
   144 		if(iTempDirName)
       
   145 			{
       
   146 			delete[] iTempDirName;
       
   147 			iTempDirName = 0;
       
   148 			}
       
   149 		return KErrCancel;
       
   150 		}
       
   151 
       
   152 	// Construct the file options.
       
   153 	if(ConstructOptions() != KErrNone)
       
   154 		{
       
   155 		return KErrGeneral;
       
   156 		}
       
   157 
       
   158 	// Construct the List.
       
   159 	if((GenTreeTraverse(pRootDir,KNodeTypeRoot)) != KErrNone )
       
   160 		{
       
   161 		return KErrGeneral;
       
   162 		}
       
   163 
       
   164 	return KErrNone;
       
   165 	}
       
   166 
       
   167 
       
   168 /**
       
   169 Creates the Image/Call to file system module.
       
   170 
       
   171 Updates the required operations to generate the data drive images.
       
   172 Deletes the temp folder if created.
       
   173 Calls the file system modules with required parameters.
       
   174 
       
   175 @param alogfile - Logfile name required for file system module.
       
   176 @return Status(r) - returns the status of file system module.
       
   177                    'KErrGeneral' - Unable to done the above operations properly.
       
   178 */
       
   179 TInt CDriveImage::CreateImage(TText* alogfile)
       
   180 	{
       
   181 
       
   182 	TInt retStatus = 0;
       
   183 	retStatus = CreateList();
       
   184 
       
   185 	if((retStatus == KErrCancel) || (retStatus == KErrNoMemory))
       
   186 		return KErrGeneral;
       
   187 
       
   188 	if(retStatus != KErrNone)
       
   189 		{
       
   190 		Print(EError,"Insufficent Memory/Not able to generate the Structure\n");
       
   191 		if(DeleteTempFolder((char*)iTempDirName) != KErrNone )
       
   192 			{
       
   193 			Print(EWarning,"Not able to delete the temp folder : %s",iTempDirName);
       
   194 			}
       
   195 		return KErrGeneral;
       
   196 		}
       
   197 
       
   198 	// Close log file.
       
   199 	H.CloseLogFile();		
       
   200 	
       
   201 	// Convert fileformat to corresponding enum value.
       
   202 	enum TFileSystem fileFormat = (TFileSystem)0;
       
   203 	FormatTranslation(iObey->iDriveFileFormat,fileFormat);
       
   204 
       
   205 	// Call to file system module. create the image.
       
   206 	if(iObey->iDataSize)
       
   207 		retStatus = CFileSystemInterFace::CreateFilesystem(&iNodeList,fileFormat,
       
   208 														(char*)iObey->iDriveFileName,
       
   209 														(char*)alogfile,
       
   210 														iObey->iConfigurableFatAttributes,																											
       
   211 														iObey->iDataSize); 
       
   212 	else
       
   213 		retStatus = CFileSystemInterFace::CreateFilesystem(&iNodeList,fileFormat,
       
   214 														(char*)iObey->iDriveFileName,
       
   215 														(char*)alogfile,
       
   216 														iObey->iConfigurableFatAttributes);														; 
       
   217 
       
   218 	//delete the temp folder.
       
   219 	if(DeleteTempFolder((char*)iTempDirName) != KErrNone )
       
   220 		{
       
   221 		cout << "Warning: Not able to delete the temp folder : " << iTempDirName << "\n" ;
       
   222 		}
       
   223 	
       
   224 	return 	retStatus;
       
   225 	}
       
   226 
       
   227 
       
   228 
       
   229 /**
       
   230 Delete the temp directory.
       
   231 
       
   232 @param aTempDirName - Temporory folder name to be deleted.
       
   233 @return Status(r) - returns the status.
       
   234                    'KErrGeneral' - Unable to done the above operations properly.
       
   235 				   'KErrNone' - successfully deleted the folder.
       
   236 */
       
   237 TInt CDriveImage::DeleteTempFolder(char* aTempDirName)
       
   238 	{
       
   239 
       
   240 	TInt fileDeleted = 1;
       
   241 	std::string dirPath(aTempDirName); 
       
   242 	std::string fileName(aTempDirName); 
       
   243 
       
   244 #ifdef __LINUX__
       
   245 
       
   246 	// Open directory
       
   247 	DIR *dirHandler = opendir(aTempDirName);
       
   248 	struct dirent *dirEntry;
       
   249 
       
   250 	if(!dirHandler)
       
   251 		return KErrGeneral;
       
   252 
       
   253 	dirPath.append("/");
       
   254 	fileName.append("/");
       
   255 
       
   256 	// Go through each entry
       
   257 	while(dirEntry = readdir(dirHandler))
       
   258 		{
       
   259 		if(dirEntry->d_type != DT_DIR) 
       
   260 			{
       
   261 			fileName.append((char*)dirEntry->d_name);
       
   262 			remove(fileName.c_str());
       
   263 			fileName.assign(dirPath);
       
   264 			}
       
   265 		}
       
   266 	//Close dir
       
   267 	if(!closedir(dirHandler))
       
   268 		{
       
   269 		fileDeleted = rmdir(aTempDirName);
       
   270 		}
       
   271 #else
       
   272 
       
   273 	WIN32_FIND_DATA FindFileData;
       
   274 	HANDLE hFind = INVALID_HANDLE_VALUE;
       
   275 
       
   276 	dirPath.append("\\*");
       
   277 	fileName.append("\\");
       
   278 	
       
   279 	// find the first file
       
   280 	hFind = FindFirstFile(dirPath.c_str(),&FindFileData);
       
   281 
       
   282 	if(hFind == INVALID_HANDLE_VALUE) 
       
   283 		return KErrGeneral;
       
   284 	
       
   285 	dirPath.assign(fileName);   
       
   286 
       
   287 	do
       
   288 	{
       
   289 	// Check for directory or file.
       
   290 	if(!(FindFileData.dwFileAttributes  & FILE_ATTRIBUTE_DIRECTORY))
       
   291 		{
       
   292 		// Delete the file.
       
   293 		fileName.append((char*)FindFileData.cFileName);
       
   294 		remove(fileName.c_str());
       
   295 		fileName.assign(dirPath);
       
   296 		}
       
   297 	} while(FindNextFile(hFind,&FindFileData));
       
   298 
       
   299 	FindClose(hFind);
       
   300 					
       
   301 	if(ERROR_NO_MORE_FILES != GetLastError())
       
   302 		{
       
   303 		cout << "Warning: FindNextFile error. Error is " << GetLastError() << "\n" ;
       
   304 		}
       
   305 
       
   306 	fileDeleted = _rmdir(aTempDirName);
       
   307 
       
   308 #endif
       
   309 
       
   310 	if(!fileDeleted)
       
   311 		return KErrNone;
       
   312 	else
       
   313 		return KErrGeneral;
       
   314 	}
       
   315 
       
   316 
       
   317 /**
       
   318 General Tree Traverse to create the List.
       
   319 Recursive call to update the list.
       
   320 
       
   321 @param anode - Current Node in the tree.
       
   322 @param anodeType - Node type(root,child,sibling)
       
   323 
       
   324 @return r - returns 'KErrNoMemory' if fails to generate the list or memory not allocated.
       
   325             or 'KErrNone'
       
   326 */
       
   327 TInt CDriveImage::GenTreeTraverse(TRomNode* anode,enum KNodeType anodeType)    
       
   328 	{
       
   329 	 
       
   330 	TInt r =0;			
       
   331 	if((r = CreateDirOrFileEntry(anode,anodeType)) != KErrNone) 
       
   332 		return KErrNoMemory;
       
   333 	 
       
   334 	if(anode->Currentchild())
       
   335 		{
       
   336 		if((r = GenTreeTraverse(anode->Currentchild(),KNodeTypeChild)) != KErrNone)
       
   337 			return KErrNoMemory;
       
   338 			
       
   339 		if(iNodeAddStore.size())	
       
   340 			iNodeAddStore.pop_back();
       
   341 
       
   342 		--iListReference;
       
   343 		}
       
   344 
       
   345 	if(anode->Currentsibling())
       
   346 		{
       
   347 		if((r = GenTreeTraverse(anode->Currentsibling(),KNodeTypeSibling)) != KErrNone)
       
   348 			return KErrNoMemory;
       
   349 		}
       
   350 	return r;
       
   351 	}
       
   352 
       
   353 
       
   354 /**
       
   355 Generate the List. required for drive image creation.
       
   356 Hidden file node is not placed in list.
       
   357 
       
   358 @param atempnode - Current Node in the tree.
       
   359 @param aType - Node type(root,child,sibling)
       
   360 
       
   361 @return r - returns 'KErrNoMemory' if memory is not allocated or 'KErrNone'
       
   362 */
       
   363 TInt CDriveImage::CreateDirOrFileEntry(TRomNode* atempnode,enum KNodeType aType)    
       
   364 	{
       
   365 
       
   366 	CDirectory* iDirectory = new CDirectory((char*)atempnode->iName);
       
   367 	if(!iDirectory)									
       
   368 		return KErrNoMemory;
       
   369 		
       
   370 	char attrib = 0 ;
       
   371 	if(atempnode->iAtt & KEntryAttReadOnly)
       
   372 		attrib |= EAttrReadOnly ;
       
   373 	if(atempnode->iAtt & KEntryAttHidden)
       
   374 		attrib |= EAttrHidden ;
       
   375 	if(atempnode->iAtt & KEntryAttSystem)
       
   376 		attrib |= EAttrSystem ;
       
   377 		
       
   378 
       
   379 	// for files only.
       
   380 	if(atempnode->iEntry)
       
   381 		{
       
   382 		iDirectory->SetEntryAttribute(attrib);
       
   383 
       
   384 		// don't place the hidden files to list.
       
   385 		if(!atempnode->iHidden)	
       
   386 			{
       
   387 			iDirectory->SetFilePath(atempnode->iEntry->iFileName);
       
   388 			iDirectory->SetFileSize(atempnode->iSize);
       
   389 			}
       
   390 		else
       
   391 			{
       
   392 			iNodeAddStore.push_back((void*)iParentInnerList);
       
   393 			++iListReference;
       
   394 			return KErrNone;  
       
   395 			}	
       
   396 		}
       
   397 	else
       
   398 		iDirectory->SetEntryAttribute(attrib | EAttrDirectory);
       
   399 
       
   400 
       
   401 	switch(aType)
       
   402 		{
       
   403 		case KNodeTypeRoot:
       
   404 			iDirectory->SetEntryAttribute(EAttrVolumeId);
       
   405 			iNodeList.push_back(iDirectory);	
       
   406 			iParentInnerList = iDirectory->GetEntryList(); 
       
   407 			break;
       
   408 					
       
   409 		case KNodeTypeChild:
       
   410 			iNodeAddStore.push_back((void*)iParentInnerList);
       
   411 			++iListReference;
       
   412 			iParentInnerList->push_back(iDirectory);
       
   413 			iParentInnerList = iDirectory->GetEntryList(); 
       
   414 			break;
       
   415 
       
   416 		case KNodeTypeSibling:									
       
   417 			iParentInnerList =(std::list<CDirectory*> *)(iNodeAddStore[iListReference-1]);
       
   418 			iParentInnerList->push_back(iDirectory);
       
   419 			iParentInnerList = iDirectory->GetEntryList();
       
   420 			break;
       
   421 
       
   422 		default: 
       
   423 			break;
       
   424 		}
       
   425 	return KErrNone;                                             
       
   426 	}
       
   427 
       
   428 
       
   429 /**
       
   430 Traverses all entries and update compress/uncompress and file attribute options.
       
   431 
       
   432 Place executables in temp folder.(if changed)
       
   433 Hidden file node is not placed in temp folder.
       
   434 
       
   435 @return r - returns 'KErrNoMemory/KErrGeneral' if fails to update the options or memory
       
   436             not allocated or else 'KErrNone' for Succesfully operation.
       
   437 */
       
   438 TInt CDriveImage::ConstructOptions() 
       
   439 	{
       
   440 
       
   441 	TInt32 len = 0;
       
   442 	TRomNode* node = TRomNode::FirstNode();
       
   443         CBytePair bpe(gFastCompress);
       
   444 	
       
   445 	while(node)
       
   446 		{
       
   447 		// Don't do anything for hidden files.
       
   448 		if(node->IsFile() && (!node->iHidden))
       
   449 			{
       
   450 		
       
   451 			TInt32 size=HFile::GetLength((TText*)node->iEntry->iFileName);    
       
   452 			if(size <= 0)
       
   453 				{
       
   454 				Print(EWarning,"File %s does not exist or is 0 bytes in length.\n",node->iEntry->iFileName);
       
   455 				}
       
   456 			node->iSize = size;
       
   457 			if(node->iEntry->iExecutable && (size > 0))
       
   458 				{
       
   459 				
       
   460 				if((node->iFileUpdate) || (node->iOverride))
       
   461 					{
       
   462 					iData = new char[(size * 2)];
       
   463 					if(!iData)
       
   464 						return KErrNoMemory;
       
   465 					
       
   466 					HMem::Set(iData, 0xff, (size * 2));
       
   467                                         TUint8* aData = (TUint8*)iData;
       
   468 					len = node->PlaceFile(aData,0,(size * 2),&bpe);
       
   469 					if(len < KErrNone)
       
   470 						{	
       
   471 						delete[] iData;
       
   472 						iData = 0;
       
   473 						return KErrGeneral;
       
   474 						}
       
   475 						
       
   476 					// Place the file in Newly created Folder. 
       
   477 					TInt r = PlaceFileTemporary(len,node);
       
   478 					delete[] iData;
       
   479 					iData = 0;
       
   480 
       
   481 					if(r != KErrNone)
       
   482 						{
       
   483 						return r;
       
   484 						}
       
   485 					} // file update end.
       
   486 				}
       
   487 			} // is file end
       
   488 		node = node->NextNode();
       
   489 		}
       
   490 	return KErrNone;
       
   491 	}
       
   492 
       
   493 
       
   494 /**
       
   495 Place the modified exe's(e32 format) in Temp Folder. 
       
   496 Place executables in temp folder.(if changed)
       
   497 
       
   498 @param afileSize    - No. of bytes to be palced in the file.
       
   499 @param acurrentNode - file node, to modify its source path.
       
   500 
       
   501 @return r - returns 'KErrNoMemory' if fails to allocate the memory.
       
   502             or 'KErrNone'
       
   503 */
       
   504 TInt CDriveImage::PlaceFileTemporary(const TInt afileSize,TRomNode* acurrentNode) 
       
   505 	{
       
   506 
       
   507 	TInt randomValue = 0;
       
   508 	char randomString[KMaxGenBuffer] = "\0";
       
   509 	unsigned char* fileSourcePath = acurrentNode->iEntry->iName;
       
   510 	std::string newFileName;
       
   511 
       
   512 	do
       
   513 		{
       
   514 		newFileName.append(iTempDirName);
       
   515 		newFileName.append("/");
       
   516 
       
   517 		if(!randomValue)	
       
   518 			{
       
   519 			newFileName.append((char*)fileSourcePath);
       
   520 			}
       
   521 		else
       
   522 			{  
       
   523 			newFileName.append(randomString);
       
   524 			newFileName.append((char*)fileSourcePath);
       
   525 			}
       
   526 
       
   527 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
   528 		ifstream test(newFileName.c_str());
       
   529 #else //!__MSVCDOTNET__
       
   530 		ifstream test(newFileName.c_str(), ios::nocreate);
       
   531 #endif //__MSVCDOTNET__
       
   532 
       
   533 		if (!test)
       
   534 			{
       
   535 			test.close();
       
   536 			ofstream driveFile((char *)newFileName.c_str(),ios::binary);
       
   537 			if (!driveFile)
       
   538 				{
       
   539 				Print(EError,"Cannot open file %s for output\n",newFileName.c_str());
       
   540 				return KErrGeneral;
       
   541 				}
       
   542 
       
   543 			driveFile.write(iData,afileSize);
       
   544 			driveFile.close();
       
   545 
       
   546 			// Update the new source path.
       
   547 			delete[] acurrentNode->iEntry->iFileName;
       
   548 			acurrentNode->iEntry->iFileName = new char[ strlen(newFileName.c_str()) + 1 ];
       
   549 			if(!acurrentNode->iEntry->iFileName)
       
   550 				return KErrNoMemory;
       
   551 				
       
   552 			strcpy(acurrentNode->iEntry->iFileName,newFileName.c_str());
       
   553 			break;
       
   554 			}
       
   555 
       
   556 		test.close();
       
   557 		newFileName.erase();
       
   558 		++randomValue;
       
   559 		sprintf(randomString,"%d",randomValue);
       
   560 	
       
   561 		}
       
   562 	while(randomValue);
       
   563 
       
   564 	return KErrNone;
       
   565 	}
       
   566 
       
   567 
       
   568 
       
   569