diff -r 22486c9c7b15 -r 378360dbbdba imgtools/romtools/rofsbuild/r_driveimage.cpp --- a/imgtools/romtools/rofsbuild/r_driveimage.cpp Wed Jun 23 17:27:59 2010 +0800 +++ b/imgtools/romtools/rofsbuild/r_driveimage.cpp Wed Jun 30 11:35:58 2010 +0800 @@ -20,7 +20,13 @@ #include #include - +#include "fsnode.h" +#include "fatimagegenerator.h" +#include +#include +#include +#include +using namespace boost ; #ifdef __LINUX__ #include @@ -48,125 +54,96 @@ #include "r_romnode.h" #include "r_rofs.h" #include "r_driveimage.h" - - -// File format supported by Rofsbuild -DriveFileFormatSupported CDriveImage::iFormatType[] = - { - {"FAT16",EFAT16}, - {"FAT32",EFAT32}, - {0,EFATINVALID} - }; - - -/** -File format conversion from char* to coresponding enum value. - -@param aUserFileFormat - pointer to user entered file format. -@param aDriveFileFormat - Reference to actual variable. -*/ -TBool CDriveImage::FormatTranslation(const char* aUserFileFormat,enum TFileSystem& aDriveFileFormat) - { - struct DriveFileFormatSupported* strPointer = iFormatType; - for( ; (strPointer->iDriveFileFormat) != '\0' ; ++strPointer ) - { - if(!strcmp(aUserFileFormat,strPointer->iDriveFileFormat)) - { - aDriveFileFormat = strPointer->iFileSystem; - return ETrue; - } - } - return EFalse; - } - - + /** Constructor: CDriveImage class @param aObey - pointer to Drive obey file. */ CDriveImage::CDriveImage(CObeyFile *aObey) - : iObey( aObey ),iParentDirEntry(0),iListReference(0),iTempDirName(NULL), iData(0) - { - } - - -/** -Destructor: CDriveImage class - -Release the resources allocated in heap. -*/ -CDriveImage::~CDriveImage() - { - iNodeAddStore.clear(); - iNodeList.clear(); - if(iData) - delete[] iData; - if(iTempDirName) - delete[] iTempDirName; - } + : iObey( aObey ) +{ +} +CDriveImage::~CDriveImage() +{ + +} /** -Creates the STL list to interface with file system module. -Creates the Temp folder for placing the executables - (those changed,due to user option like compression,un-compression & fileattribute) -Updates the excutable options (file attributes, compression etc) - -@return Status - 'KErrNone' - successfully done above operations. - 'KErrNoMemory' - Not able to allocate the memory. - 'KErrGeneral' - Unable to done the above operations. -*/ -TInt CDriveImage::CreateList() - { - - TRomNode* pRootDir = iObey->iRootDirectory; - TInt16 dirCheck = 1; - TInt retStatus = 0; - - // For Creating the temp folder. - iTempDirName = new char[KMaxGenBuffer]; - if(!iTempDirName) - return KErrNoMemory; - - // Create the temp folder. - // Check for folder exist, if exist it loops until dir created or loop exit. - while(dirCheck) - { - sprintf(iTempDirName,"%s%05d","temp",dirCheck); - retStatus = MKDIR(iTempDirName); - if(!retStatus) - break; - - ++dirCheck; + * + */ +TFSNode* CDriveImage::PrepareFileSystem(TRomNode* aRomNode){ + TUint8 attrib ; + TFSNode* root = 0; + TRomNode* romNode = aRomNode; + stack > nodesStack ; + TFSNode* parentFS = 0 ; + TFSNode* curFS = 0; + bool err = false ; + while(1) { + attrib = 0 ; + if(romNode->iAtt & KEntryAttReadOnly) + attrib |= ATTR_READ_ONLY ; + if(romNode->iAtt & KEntryAttHidden) + attrib |= ATTR_HIDDEN ; + if(romNode->iAtt & KEntryAttSystem) + attrib |= ATTR_SYSTEM ; + if(romNode->IsDirectory()) { + curFS = new(std::nothrow) TFSNode(parentFS,romNode->iName,attrib | ATTR_DIRECTORY); + if(!curFS){ + err = true ; + break ; + } + if(!root) root = curFS ; + time_t now = time(NULL); + curFS->Init(now,now,now,0); + TRomNode* child = romNode->Currentchild(); + if(child){ + TRomNode* sibling = romNode->Currentsibling(); + if(sibling) + nodesStack.push(make_pair(sibling,parentFS)); + romNode = child ; + parentFS = curFS ; + continue ; + } } - - if(!dirCheck) - { - Print(EError,"Unable to Create the temp folder,Check directory settings.\n"); - if(iTempDirName) - { - delete[] iTempDirName; - iTempDirName = 0; - } - return KErrCancel; + else { // file + curFS = new(std::nothrow) TFSNode(parentFS,romNode->iEntry->iName,attrib,romNode->iEntry->iFileName); + if(!curFS){ + err = true ; + break ; + } + + if(!root) root = curFS ; + struct stat statbuf ; + stat(romNode->iEntry->iFileName, &statbuf); + curFS->Init(statbuf.st_ctime,statbuf.st_atime,statbuf.st_mtime,statbuf.st_size); + + } + + TRomNode* sibling = romNode->Currentsibling(); + if(sibling) { + romNode = sibling ; } - - // Construct the file options. - if(ConstructOptions() != KErrNone) - { - return KErrGeneral; - } - - // Construct the List. - if((GenTreeTraverse(pRootDir,KNodeTypeRoot)) != KErrNone ) - { - return KErrGeneral; - } - - return KErrNone; + else { + if(nodesStack.empty()) { + break ; + } + else { + romNode = nodesStack.top().first; + parentFS = nodesStack.top().second ; + nodesStack.pop() ; + + } + } + } + if(err) { + if(root) delete root ; + return NULL ; } - + return root ; +} /** Creates the Image/Call to file system module. @@ -179,396 +156,31 @@ @return Status(r) - returns the status of file system module. 'KErrGeneral' - Unable to done the above operations properly. */ -TInt CDriveImage::CreateImage(const char* alogfile) - { - - TInt retStatus = 0; - retStatus = CreateList(); - - if((retStatus == KErrCancel) || (retStatus == KErrNoMemory)) - return KErrGeneral; - - if(retStatus != KErrNone) - { - Print(EError,"Insufficent Memory/Not able to generate the Structure\n"); - if(DeleteTempFolder(iTempDirName) != KErrNone ) - { - Print(EWarning,"Not able to delete the temp folder : %s",iTempDirName); - } - return KErrGeneral; - } - - // Close log file. - H.CloseLogFile(); +TInt CDriveImage::CreateImage(const char* alogfile) { - // Convert fileformat to corresponding enum value. - enum TFileSystem fileFormat = (TFileSystem)0; - FormatTranslation(iObey->iDriveFileFormat,fileFormat); - - // Call to file system module. create the image. - if(iObey->iDataSize) - retStatus = CFileSystemInterFace::CreateFilesystem(&iNodeList,fileFormat, - (char*)iObey->iDriveFileName, - (char*)alogfile, - iObey->iConfigurableFatAttributes, - iObey->iDataSize); - else - retStatus = CFileSystemInterFace::CreateFilesystem(&iNodeList,fileFormat, - (char*)iObey->iDriveFileName, - (char*)alogfile, - iObey->iConfigurableFatAttributes); ; - - //delete the temp folder. - if(DeleteTempFolder(iTempDirName) != KErrNone ) - { - cout << "Warning: Not able to delete the temp folder : " << iTempDirName << "\n" ; - } - - return retStatus; + TSupportedFatType fst = EFatUnknown ; + if(stricmp(iObey->iDriveFileFormat,"FAT16") == 0) + fst = EFat16 ; + else if(stricmp(iObey->iDriveFileFormat,"FAT32") == 0) + fst = EFat32 ; + if(EFatUnknown == fst){ + Print(EError,"Unsupported FAT type : %s",iObey->iDriveFileFormat); + return KErrGeneral ; } - - - -/** -Delete the temp directory. - -@param aTempDirName - Temporory folder name to be deleted. -@return Status(r) - returns the status. - 'KErrGeneral' - Unable to done the above operations properly. - 'KErrNone' - successfully deleted the folder. -*/ -TInt CDriveImage::DeleteTempFolder(const char* aTempDirName) - { - - TInt fileDeleted = 1; - string dirPath(aTempDirName); - string fileName(aTempDirName); - -#ifdef __LINUX__ - - // Open directory - DIR *dirHandler = opendir(aTempDirName); - struct dirent *dirEntry; - - if(!dirHandler) - return KErrGeneral; - - dirPath.append("/"); - fileName.append("/"); - - // Go through each entry - while((dirEntry = readdir(dirHandler))) - { - if(dirEntry->d_type != DT_DIR) - { - fileName.append((char*)dirEntry->d_name); - remove(fileName.c_str()); - fileName.assign(dirPath); - } - } - //Close dir - if(!closedir(dirHandler)) - { - fileDeleted = rmdir(aTempDirName); - } -#else - - WIN32_FIND_DATA FindFileData; - HANDLE hFind = INVALID_HANDLE_VALUE; - - dirPath.append("\\*"); - fileName.append("\\"); - - // find the first file - hFind = FindFirstFile(dirPath.c_str(),&FindFileData); - - if(hFind == INVALID_HANDLE_VALUE) - return KErrGeneral; + + TFatImgGenerator generator(fst,iObey->iConfigurableFatAttributes); - dirPath.assign(fileName); - - do - { - // Check for directory or file. - if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - // Delete the file. - fileName.append((char*)FindFileData.cFileName); - remove(fileName.c_str()); - fileName.assign(dirPath); - } - } while(FindNextFile(hFind,&FindFileData)); - - FindClose(hFind); - - if(ERROR_NO_MORE_FILES != GetLastError()) - { - cout << "Warning: FindNextFile error. Error is " << GetLastError() << "\n" ; - } - - fileDeleted = _rmdir(aTempDirName); - -#endif - - if(!fileDeleted) - return KErrNone; - else - return KErrGeneral; + if(!generator.IsValid()){ + return KErrGeneral; } - - -/** -General Tree Traverse to create the List. -Recursive call to update the list. - -@param anode - Current Node in the tree. -@param anodeType - Node type(root,child,sibling) - -@return r - returns 'KErrNoMemory' if fails to generate the list or memory not allocated. - or 'KErrNone' -*/ -TInt CDriveImage::GenTreeTraverse(TRomNode* anode,enum KNodeType anodeType) - { - - TInt r =0; - if((r = CreateDirOrFileEntry(anode,anodeType)) != KErrNone) - return KErrNoMemory; - - if(anode->Currentchild()) - { - if((r = GenTreeTraverse(anode->Currentchild(),KNodeTypeChild)) != KErrNone) - return KErrNoMemory; - - if(iNodeAddStore.size()) - iNodeAddStore.pop_back(); - - --iListReference; - } - - if(anode->Currentsibling()) - { - if((r = GenTreeTraverse(anode->Currentsibling(),KNodeTypeSibling)) != KErrNone) - return KErrNoMemory; - } - return r; - } - - -/** -Generate the List. required for drive image creation. -Hidden file node is not placed in list. - -@param atempnode - Current Node in the tree. -@param aType - Node type(root,child,sibling) - -@return r - returns 'KErrNoMemory' if memory is not allocated or 'KErrNone' -*/ -TInt CDriveImage::CreateDirOrFileEntry(TRomNode* atempnode,enum KNodeType aType) - { - - CDirectory* parentDirectory = NULL ; - if(KNodeTypeChild == aType) - parentDirectory = iParentDirEntry; - else if(KNodeTypeSibling == aType) - parentDirectory = (CDirectory*)(iNodeAddStore[iListReference-1]); + TFSNode* root = PrepareFileSystem(iObey->iRootDirectory); + if(!root) + return KErrGeneral; - CDirectory* iDirectory = new CDirectory(atempnode->iName,parentDirectory); - if(!iDirectory) - return KErrNoMemory; + + TInt retVal = generator.Execute(root,iObey->iDriveFileName) ? KErrNone : KErrGeneral; + + delete root ; - char attrib = 0 ; - if(atempnode->iAtt & KEntryAttReadOnly) - attrib |= EAttrReadOnly ; - if(atempnode->iAtt & KEntryAttHidden) - attrib |= EAttrHidden ; - if(atempnode->iAtt & KEntryAttSystem) - attrib |= EAttrSystem ; - - - // for files only. - if(atempnode->iEntry) - { - iDirectory->SetEntryAttribute(attrib); - - // don't place the hidden files to list. - if(!atempnode->iHidden) - { - iDirectory->SetFilePath(atempnode->iEntry->iFileName); - iDirectory->SetFileSize(atempnode->iSize); - } - else - { - iNodeAddStore.push_back((void*)iParentDirEntry); - ++iListReference; - return KErrNone; - } - } - else - iDirectory->SetEntryAttribute(attrib | EAttrDirectory); - - - switch(aType) - { - case KNodeTypeRoot: - iDirectory->SetEntryAttribute(EAttrVolumeId); - iNodeList.push_back(iDirectory); - iParentDirEntry = iDirectory; - break; - - case KNodeTypeChild: - iNodeAddStore.push_back((void*)iParentDirEntry); - ++iListReference; - parentDirectory->InsertIntoEntryList(iDirectory); - iParentDirEntry = iDirectory ; - break; - - case KNodeTypeSibling: - parentDirectory->InsertIntoEntryList(iDirectory); - iParentDirEntry = iDirectory ; - break; - - default: - break; - } - return KErrNone; - } - - -/** -Traverses all entries and update compress/uncompress and file attribute options. - -Place executables in temp folder.(if changed) -Hidden file node is not placed in temp folder. - -@return r - returns 'KErrNoMemory/KErrGeneral' if fails to update the options or memory - not allocated or else 'KErrNone' for Succesfully operation. -*/ -TInt CDriveImage::ConstructOptions() { - - TInt32 len = 0; - TRomNode* node = TRomNode::FirstNode(); - CBytePair bpe; - - while(node) - { - // Don't do anything for hidden files. - if(node->IsFile() && (!node->iHidden)) - { - - TInt32 size=HFile::GetLength(node->iEntry->iFileName); - if(size <= 0) - { - Print(EWarning,"File %s does not exist or is 0 bytes in length.\n",node->iEntry->iFileName); - } - node->iSize = size; - if(node->iEntry->iExecutable && (size > 0)) - { - - if((node->iFileUpdate) || (node->iOverride)) - { - size_t allocSize = size << 1 ; - iData = new char[allocSize]; - if(!iData) - return KErrNoMemory; - - HMem::Set(iData, 0xff, allocSize); - TUint8* aData = (TUint8*)iData; - len = node->PlaceFile(aData,0,allocSize,&bpe); - if(len < KErrNone) - { - delete[] iData; - iData = 0; - return KErrGeneral; - } - - // Place the file in Newly created Folder. - TInt r = PlaceFileTemporary(len,node); - delete[] iData; - iData = 0; - - if(r != KErrNone) - { - return r; - } - } // file update end. - } - } // is file end - node = node->NextNode(); - } - return KErrNone; - } - - -/** -Place the modified exe's(e32 format) in Temp Folder. -Place executables in temp folder.(if changed) - -@param afileSize - No. of bytes to be palced in the file. -@param acurrentNode - file node, to modify its source path. - -@return r - returns 'KErrNoMemory' if fails to allocate the memory. - or 'KErrNone' -*/ -TInt CDriveImage::PlaceFileTemporary(const TInt afileSize,TRomNode* acurrentNode) - { - - TInt randomValue = 0; - char randomString[KMaxGenBuffer] = "\0"; - char* fileSourcePath = acurrentNode->iEntry->iName; - string newFileName; - - do - { - newFileName.append(iTempDirName); - newFileName.append("/"); - - if(!randomValue) - { - newFileName.append(fileSourcePath); - } - else - { - newFileName.append(randomString); - newFileName.append(fileSourcePath); - } - - - ifstream test(newFileName.c_str()); - if (!test) - { - test.close(); - ofstream driveFile(newFileName.c_str(),ios_base::binary); - if (!driveFile) - { - Print(EError,"Cannot open file %s for output\n",newFileName.c_str()); - return KErrGeneral; - } - - driveFile.write(iData,afileSize); - driveFile.close(); - - // Update the new source path. - delete[] acurrentNode->iEntry->iFileName; - acurrentNode->iEntry->iFileName = new char[ newFileName.length() + 1 ]; - if(!acurrentNode->iEntry->iFileName) - return KErrNoMemory; - - memcpy(acurrentNode->iEntry->iFileName,newFileName.c_str(),newFileName.length()); - acurrentNode->iEntry->iFileName[newFileName.length()] = 0; - break; - } - - test.close(); - newFileName.erase(); - ++randomValue; - sprintf(randomString,"%d",randomValue); - - } - while(randomValue); - - return KErrNone; - } - - - - + return retVal; +}