--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofilerui/ui/hb/src/piprofilerengineprivate.cpp Wed Jun 09 09:42:37 2010 +0300
@@ -0,0 +1,678 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <e32std.h>
+#include <qstring.h>
+#include <qlist.h>
+#include <qstringlist.h>
+#include <f32file.h>
+#include <xqconversions.h>
+#include <utf.h>
+#include <bautils.h>
+#include <sysutil.h>
+#include "piprofilerengineprivate.h"
+#include <piprofiler/ProfilerSession.h>
+#include "pluginattributes.h"
+#include "generalattributes.h"
+#include "piprofilerengine.h"
+
+// literals for default general setting values
+_LIT8(KTraceOutput, "file_system");
+_LIT8(KTraceDebugOutput, "debug_output");
+_LIT8(KProfilerDefaultDrive, "E:\\data");
+_LIT8(KProfilerDefaultPrefix, "Profiler_#");
+_LIT(KProfilerEngineExe, "PIProfilerEngine.exe");
+const TInt KProfilerDefaultTimedSamplingPeriod = 60; // Sampling time in seconds
+
+// ---------------------------------------------------------------------------
+
+PIProfilerEnginePrivate::PIProfilerEnginePrivate(PIProfilerEngine *aEngine) :
+ iPublic(aEngine), iSamplerAttributes(0), iStatusChecker(0), iLeaveProfilingOnAfterClosing(
+ EFalse)
+{
+
+}
+
+// ---------------------------------------------------------------------------
+
+PIProfilerEnginePrivate::~PIProfilerEnginePrivate()
+{
+
+ // remove profiler client
+ RProfiler::RemoveClient();
+ // Terminate engine in case it is running.
+ if (iLeaveProfilingOnAfterClosing == EFalse) {
+ terminateEngine();
+ }
+
+ // delete sampler attributes.
+ if (iSamplerAttributes) {
+ delete iSamplerAttributes;
+ iSamplerAttributes = 0;
+ }
+
+ if (iStatusChecker) {
+ iStatusChecker->Cancel();
+ delete iStatusChecker;
+ iStatusChecker = NULL;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+bool PIProfilerEnginePrivate::Init()
+{
+ TRAPD(error, this->LaunchEngineL());
+ if (error != KErrNone) {
+ return false;
+ }
+
+ // initialize attribute arrays
+
+ TRAP(error, iSamplerAttributes = new (ELeave) CArrayFixFlat<TSamplerAttributes> (20)); // max sampler count is 20
+ if (error != KErrNone) {
+ return false;
+ }
+
+ // engine status checker
+ TRAP(error, iStatusChecker = CProfilerEngineStatusChecker::NewL());
+ if (error != KErrNone) {
+ return false;
+ }
+
+ iStatusChecker->SetObserver(this);
+
+ TRAP(error, LoadGeneralSettingsL());
+ if (error != KErrNone) {
+ return false;
+ }
+
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+
+int PIProfilerEnginePrivate::LaunchEngineL()
+{
+
+ TRequestStatus stat = KRequestPending;
+ RProcess proc;
+
+ TInt err(KErrNone);
+
+ // check if process exists
+ err = FindProcessL(proc);
+
+ // check if already exists and don't start a new eshell profiling
+ if (err == KErrNotFound) {
+ // try create new process
+ err = proc.Create(KProfilerEngineExe, _L(""));
+
+ // check if RProcess::Create() succeeded
+ if (err == KErrNone) {
+ // Trigger rendezvous on the supplied TRequestStatus object
+ proc.Rendezvous(stat);
+
+ // kick off the engine process
+ proc.Resume();
+
+ // wait for the constructor to complete
+ User::WaitForRequest(stat);
+
+ // just lose the handle
+ proc.Close();
+ }
+ }
+
+ // Increase the client reference count in server:
+ AttachClient();
+}
+
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::AttachClient()
+{
+ RProfiler::AttachClient();
+}
+// ---------------------------------------------------------------------------
+
+int PIProfilerEnginePrivate::FindProcessL(RProcess& aProc)
+{
+ TProcessId engId;
+ TFindProcess procName;
+ procName.Find(_L("PIProfilerEngine.exe*"));
+ TFullName aResult;
+ TFullName aResult2;
+ TInt err(KErrNone);
+
+ // find the first appearance
+ err = procName.Next(aResult);
+ if (err != KErrNone) {
+ // did not find any engine process
+ return err;
+ }
+ else {
+ err = aProc.Open(procName);
+ if (err == KErrNone) {
+ if (aProc.ExitCategory().Length() > 0) {
+ aProc.Close();
+ // process already exited => create a new one
+ return KErrNotFound;
+ }
+ aProc.Close();
+ }
+ }
+
+ // check now if a second appearance exists in process list,
+ // i.e. engine started from eshell => two engine processes appear in normal case
+ procName.Next(aResult2);
+
+ // check if aResult2 contained the second appearance of profiler engine
+ if(aResult2.CompareF(aResult) > 0)
+ {
+ // other process found, i.e. right process to communicate with, in case started from eshell
+ err = aProc.Open(procName);
+ if(err == KErrNone)
+ {
+ if(aProc.ExitCategory().Length() > 0)
+ {
+ // process already exited => create a new one
+ return KErrNotFound;
+ }
+ aProc.Close();
+ }
+ }
+
+ return err;
+}
+
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::terminateEngine()
+{
+ // exit profiler engine
+ RProfiler::ExitProfiler();
+}
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::NotifyUIReady()
+{
+ // load initial plugins
+ loadPlugins();
+
+ // get the initial state
+ int initialState = iStatusChecker->GetInitialState();
+ if (initialState == ERunning) {
+ HandleProfilerStatusChange(ERunning);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+
+void PIProfilerEnginePrivate::loadPlugins()
+{
+ // get samplers from Profiler Engine (client-server session)
+ // and add the to the samplers list for the first time
+ LOGTEXT(_L("CProfilerGuiModel::LoadPlugins - get sampler plugins"));
+
+ TInt err = RProfiler::GetSamplerAttributes(*iSamplerAttributes);
+
+ // check if engine provided a list of samplers
+ if (err != KErrNone) {
+ // could not get samplers from engine
+ LOGTEXT(_L("CProfilerGuiModel::LoadPlugins - failed to connect engine"));
+ }
+ else {
+ LOGTEXT(_L("CProfilerGuiModel::LoadPlugins - adding new samplers into view"));
+ addNewSamplers(*iSamplerAttributes);
+ }LOGTEXT(_L("CProfilerGuiModel::LoadPlugins - exit"));
+}
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::addNewSamplers(CArrayFixFlat<TSamplerAttributes>& aAttributes)
+{
+ TSamplerAttributes item;
+
+ TInt count(aAttributes.Count());
+
+ // loop the attribute array and insert them into view list
+
+ QList<PluginAttributes> samplerList;
+
+ for (TInt i(0); i < count; i++) {
+ // get a TSamplerAttributes from list at a time
+ item = aAttributes.At(i);
+
+ PluginAttributes samplerAttributes;
+ convertTSamplerAttributesToPluginAttributes(item, samplerAttributes);
+
+ samplerList.append(samplerAttributes);
+ }
+
+ emit iPublic->pluginListUpdated(samplerList);
+
+}
+
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::convertTSamplerAttributesToPluginAttributes(
+ TSamplerAttributes &tSamplerAttributes, PluginAttributes &samplerAttributes)
+{
+
+ samplerAttributes.mUid = tSamplerAttributes.iUid;
+ samplerAttributes.mSampleRate = tSamplerAttributes.iSampleRate;
+ samplerAttributes.mEnabled = tSamplerAttributes.iEnabled;
+ samplerAttributes.mIsHidden = tSamplerAttributes.iIsHidden;
+ samplerAttributes.mItemCount = tSamplerAttributes.iItemCount;
+
+ TBuf16<8> temp8;
+ temp8.Copy(tSamplerAttributes.iShortName);
+ samplerAttributes.mShortName = QString((QChar*) temp8.Ptr(), temp8.Length());
+
+ TBuf16<64> temp64;
+ temp64.Copy(tSamplerAttributes.iName);
+ samplerAttributes.mName = QString((QChar*) temp64.Ptr(), temp64.Length());
+
+ TBuf16<256> temp256;
+ temp256.Copy(tSamplerAttributes.iDescription);
+ samplerAttributes.mDescription = QString((QChar*) temp256.Ptr(), temp256.Length());
+
+ convertTSettingItemToSettingItem(tSamplerAttributes.iSettingItem1,
+ samplerAttributes.mSettingItem1);
+ convertTSettingItemToSettingItem(tSamplerAttributes.iSettingItem2,
+ samplerAttributes.mSettingItem2);
+ convertTSettingItemToSettingItem(tSamplerAttributes.iSettingItem3,
+ samplerAttributes.mSettingItem3);
+ convertTSettingItemToSettingItem(tSamplerAttributes.iSettingItem4,
+ samplerAttributes.mSettingItem4);
+ convertTSettingItemToSettingItem(tSamplerAttributes.iSettingItem5,
+ samplerAttributes.mSettingItem5);
+ convertTSettingItemToSettingItem(tSamplerAttributes.iSettingItem6,
+ samplerAttributes.mSettingItem6);
+}
+
+// ---------------------------------------------------------------------------
+
+bool PIProfilerEnginePrivate::SavePluginSettings(const PluginAttributes &samplerAttributes)
+{
+ for (int index = 0; index < iSamplerAttributes->Count(); index++) {
+ if (samplerAttributes.mUid == this->iSamplerAttributes->At(index).iUid) {
+ iSamplerAttributes->At(index).iEnabled = samplerAttributes.mEnabled;
+ iSamplerAttributes->At(index).iSampleRate = samplerAttributes.mSampleRate;
+
+ convertSettingItemToTSettingItem(this->iSamplerAttributes->At(index).iSettingItem1,
+ samplerAttributes.mSettingItem1);
+ convertSettingItemToTSettingItem(this->iSamplerAttributes->At(index).iSettingItem2,
+ samplerAttributes.mSettingItem2);
+ convertSettingItemToTSettingItem(this->iSamplerAttributes->At(index).iSettingItem3,
+ samplerAttributes.mSettingItem3);
+ convertSettingItemToTSettingItem(this->iSamplerAttributes->At(index).iSettingItem4,
+ samplerAttributes.mSettingItem4);
+ convertSettingItemToTSettingItem(this->iSamplerAttributes->At(index).iSettingItem5,
+ samplerAttributes.mSettingItem5);
+ convertSettingItemToTSettingItem(this->iSamplerAttributes->At(index).iSettingItem6,
+ samplerAttributes.mSettingItem6);
+
+ TSamplerAttributes attr = iSamplerAttributes->At(index);
+
+ if (RProfiler::SetSamplerAttributes(this->iSamplerAttributes->At(index)) == KErrNone) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ return false;
+
+}
+
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::StartAllSamplerItemsL(TProfilingMode aProfilingMode)
+{
+ TBuf<256> activeWriterDes;
+ TBuf8<256> writer8;
+
+ //iState = MProfilerStatusObserver::EInitializing;
+
+ RProfiler::TProfilingMode profilingMode = aProfilingMode == EProfilingModeTimed
+ ? RProfiler::EProfilingModeTimed : RProfiler::EProfilingModeNormal;
+
+ // try to start profiling process through client-server interface
+ if (RProfiler::StartSampling(profilingMode) == KErrNotFound) {
+ // profiler stopped (e.g. from eshell) and must be restarted
+ LaunchEngineL();
+ // try to launch sampling again
+ RProfiler::StartSampling(profilingMode);
+ }
+}
+
+// ---------------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::StopProfiling()
+{
+ // Stop profiling process through CS session
+ RProfiler::StopSampling();
+
+}
+
+// --------------------------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::HandleProfilerStatusChange(KProfilerStatus aStatus)
+{
+ if (aStatus == EIdle || aStatus == ERunning) {
+
+ if (iGeneralAttributes.iTraceOutput == KTraceOutput) {
+
+ TBuf<256> buf;
+ // get profiler file name
+ TBool valu = RProfiler::GetFileName(buf);
+
+ QString filename = QString((QChar*) buf.Ptr(), buf.Length());
+
+ // Let ui know that status has changed
+
+ if (aStatus == EIdle) {
+ QString text = QString("Wrote trace data to: \n");
+ text.append(filename);
+ emit iPublic->profilingStatusChanged(PI_FINISHED_SUCCEFULLY, text,
+ PI_PROFILINGMODENORMAL, PI_FILE_OUTPUT);
+ }
+ else if (aStatus == ERunning) {
+ QString text = QString("Writing trace data to: \n");
+ text.append(filename);
+ emit iPublic->profilingStatusChanged(PI_PROFILING, text, PI_PROFILINGMODENORMAL,
+ PI_FILE_OUTPUT);
+ }
+ }
+ else {
+ // Let ui know that status has changed
+ if (aStatus == EIdle) {
+ emit iPublic->profilingStatusChanged(PI_FINISHED_SUCCEFULLY, QString(
+ "Wrote trace data to debug output"), PI_PROFILINGMODENORMAL, PI_DEBUG_OUTPUT);
+ }
+ else if (aStatus == ERunning) {
+ emit iPublic->profilingStatusChanged(PI_PROFILING, QString(
+ "Writing trace data to debug output"), PI_PROFILINGMODENORMAL, PI_DEBUG_OUTPUT);
+ }
+ }
+ }
+
+}
+
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::HandleProfilerErrorL(TInt aError)
+{
+ {
+ QString errorMsg = QString("Error: ");
+ QString KNoMemory = QString("Cannot write to file, check settings");
+
+ // message from pwr sampler
+ if (aError < -1000) {
+ errorMsg.append(QString("Stop other power measurement tools!"));
+ }
+ else if (aError == KErrAlreadyExists || aError == 11) {
+ errorMsg.append(QString("Close old Profiler before start!"));
+ }
+ else if (aError == KErrNotReady) {
+ errorMsg.append(QString("Memory card removed, failed to write!"));
+ }
+ else if (aError == KErrPathNotFound) {
+ errorMsg.append(QString("Given trace data location does not exist"));
+ }
+ else {
+ if (aError == KErrNoMemory || aError == KErrOverflow || aError == KErrDirFull || aError
+ == KErrDiskFull || aError == KErrNotReady) {
+ errorMsg.append(KNoMemory);
+ }
+ else {
+ errorMsg.append(QString("code: "));
+ errorMsg.append(aError);
+ }
+ }
+
+ emit iPublic->profilingStatusChanged(PI_ERROR, errorMsg);
+ }
+
+}
+// ---------------------------------------------------------------------------
+
+bool PIProfilerEnginePrivate::StartProfiling()
+{
+ TRAPD(error, this->StartAllSamplerItemsL(PIProfilerEnginePrivate::EProfilingModeNormal));
+ if (error == KErrNone) {
+ return true;
+ }
+ return false;
+
+}
+
+// ---------------------------------------------------------------------------
+
+bool PIProfilerEnginePrivate::StartTimedProfiling()
+{
+ TRAPD(error, this->StartAllSamplerItemsL(PIProfilerEnginePrivate::EProfilingModeTimed));
+ if (error == KErrNone) {
+ return true;
+ }
+ return false;
+}
+
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::convertTGeneralAttributesToGeneralAttributes(
+ TGeneralAttributes &tSamplerAttributes, GeneralAttributes &samplerAttributes)
+{
+ samplerAttributes.mTimedSamplingPeriod = tSamplerAttributes.iTimedSamplingPeriod;
+ int test = tSamplerAttributes.iSaveFileDrive.Length();
+ TBuf16<KPrefixMaxLength> test2;
+ test2.Copy(tSamplerAttributes.iSaveFileDrive);
+ samplerAttributes.mSaveFileDrive = QString((QChar*) test2.Ptr(), test2.Length());
+ test2.Copy(tSamplerAttributes.iTraceFilePrefix);
+ samplerAttributes.mTraceFilePrefix = QString((QChar*) test2.Ptr(), test2.Length());
+ test2.Copy(tSamplerAttributes.iTraceOutput);
+ samplerAttributes.mTraceOutput = QString((QChar*) test2.Ptr(), test2.Length());
+}
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::convertGeneralAttributesToTGeneralAttributes(
+ TGeneralAttributes &tSamplerAttributes, GeneralAttributes &samplerAttributes)
+{
+ tSamplerAttributes.iTimedSamplingPeriod = samplerAttributes.mTimedSamplingPeriod;
+
+ tSamplerAttributes.iTraceOutput.Copy(TBuf<KPrefixMaxLength> (
+ samplerAttributes.mTraceOutput.utf16()));
+ tSamplerAttributes.iSaveFileDrive.Copy(TBuf<KPrefixMaxLength> (
+ samplerAttributes.mSaveFileDrive.utf16()));
+ tSamplerAttributes.iTraceFilePrefix.Copy(TBuf<KPrefixMaxLength> (
+ samplerAttributes.mTraceFilePrefix.utf16()));
+
+}
+// ---------------------------------------------------------------------------
+
+TInt PIProfilerEnginePrivate::LoadGeneralSettingsL()
+{
+ // local variable for getting saved settings from profiler engine
+ TGeneralAttributes generalAttr;
+ TInt err(KErrNone);
+
+ // before loading saved settings (from settings file) set the default values
+ iGeneralAttributes.iTraceOutput.Copy(KTraceOutput);
+ iGeneralAttributes.iTraceFilePrefix.Copy(KProfilerDefaultPrefix);
+ iGeneralAttributes.iSaveFileDrive.Copy(KProfilerDefaultDrive);
+ iGeneralAttributes.iTimedSamplingPeriod = KProfilerDefaultTimedSamplingPeriod;
+
+ // request to
+ err = RProfiler::GetGeneralAttributes(generalAttr);
+
+ // check that request succesfull
+ if (err != KErrNone) {
+ // could not connect profiler engine, use
+ return err;
+ }
+
+ // check if saved settings different than the default
+ if (generalAttr.iTraceOutput.MatchF(iGeneralAttributes.iTraceOutput) == KErrNotFound) {
+ iGeneralAttributes.iTraceOutput.Copy(generalAttr.iTraceOutput);
+ }
+
+ if (generalAttr.iTraceFilePrefix.MatchF(iGeneralAttributes.iTraceFilePrefix) == KErrNotFound) {
+ iGeneralAttributes.iTraceFilePrefix.Copy(generalAttr.iTraceFilePrefix);
+ }
+
+ if (generalAttr.iSaveFileDrive.MatchF(iGeneralAttributes.iSaveFileDrive) == KErrNotFound) {
+ iGeneralAttributes.iSaveFileDrive.Copy(generalAttr.iSaveFileDrive);
+ }
+
+ if (generalAttr.iTimedSamplingPeriod > 0) {
+ iGeneralAttributes.iTimedSamplingPeriod = generalAttr.iTimedSamplingPeriod;
+ }
+
+ return err;
+}
+
+// ---------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::GetGeneralSettings(GeneralAttributes &settings)
+{
+ convertTGeneralAttributesToGeneralAttributes(iGeneralAttributes, settings);
+}
+// ---------------------------------------------------------------------------
+
+bool PIProfilerEnginePrivate::SaveGeneralSettings(GeneralAttributes &settings)
+{
+ convertGeneralAttributesToTGeneralAttributes(iGeneralAttributes, settings);
+ TRAPD(error, SaveGeneralSettingsL());
+ if (error != KErrNone) {
+ return false;
+ }
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::SaveGeneralSettingsL()
+{
+ TInt err(KErrNone);
+
+ // save general attributes to Profiler Engine
+ err = RProfiler::SetGeneralAttributes(iGeneralAttributes);
+
+ // check if save failed
+ if (err == KErrNotFound) {
+ // profiler stopped (e.g. from eshell) and must be restarted
+ LaunchEngineL();
+
+ err = RProfiler::SetGeneralAttributes(iGeneralAttributes);
+ if (err != KErrNone) {
+ // leave no use to continue
+ User::Leave(err);
+ }
+ }
+}
+// --------------------------------------------------------------------------------------------
+
+int PIProfilerEnginePrivate::GetTimeLimit()
+{
+ return iGeneralAttributes.iTimedSamplingPeriod;
+}
+
+// --------------------------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::convertTSettingItemToSettingItem(TSettingItem &tSettingItem,
+ SettingItem &settingItem)
+{
+
+ settingItem.mType = tSettingItem.iType;
+ settingItem.mSettingDescription = QString((QChar*) tSettingItem.iSettingDescription.Ptr(),
+ tSettingItem.iSettingDescription.Length());
+ settingItem.mSettingText = QString((QChar*) tSettingItem.iSettingText.Ptr(),
+ tSettingItem.iSettingText.Length());
+ settingItem.mUIText = QString((QChar*) tSettingItem.iUIText.Ptr(),
+ tSettingItem.iUIText.Length());
+ settingItem.mValue = QString((QChar*) tSettingItem.iValue.Ptr(), tSettingItem.iValue.Length());
+
+}
+// --------------------------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::convertSettingItemToTSettingItem(TSettingItem &tSettingItem,
+ const SettingItem &settingItem)
+{
+ tSettingItem.iType = settingItem.mType;
+ tSettingItem.iSettingDescription.Copy(TBuf<256> (settingItem.mSettingDescription.utf16()));
+ tSettingItem.iSettingText.Copy(TBuf<64> (settingItem.mSettingText.utf16()));
+ tSettingItem.iUIText.Copy(TBuf<64> (settingItem.mUIText.utf16()));
+ tSettingItem.iValue.Copy(TBuf<128> (settingItem.mValue.utf16()));
+
+}
+
+// --------------------------------------------------------------------------------------------
+
+void PIProfilerEnginePrivate::LeaveProfilingOnAfterClosing()
+{
+ iLeaveProfilingOnAfterClosing = ETrue;
+}
+
+// --------------------------------------------------------------------------------------------
+
+bool PIProfilerEnginePrivate::CheckTraceLocationSanity(QString& location)
+{
+ TBool value = EFalse;
+
+ TBuf8<KPrefixMaxLength> fileLocation;
+ fileLocation.Copy(TBuf<KPrefixMaxLength> (location.utf16()));
+ TRAPD(error, value = CheckTraceLocationSanityL(fileLocation));
+ if (error != KErrNone) {
+ return false;
+ }
+ return value;
+}
+
+// --------------------------------------------------------------------------------------------
+
+TBool PIProfilerEnginePrivate::CheckTraceLocationSanityL(TBuf8<KPrefixMaxLength> &aAttr)
+{
+ RFs fs;
+ User::LeaveIfError(fs.Connect());
+
+ TBuf<32> drive;
+
+ CnvUtfConverter::ConvertToUnicodeFromUtf8(drive, aAttr);
+
+ TDriveUnit driveUnit = TDriveUnit(drive);
+
+ TBool ret(EFalse);
+
+ // check that the root folder is correct
+ if (drive.Length() > 2 && BaflUtils::CheckFolder(fs, drive.Left(3)) == KErrNone) {
+ // check then if drive has still some space
+ if (!SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, driveUnit)) {
+ ret = ETrue;
+ }
+ }
+
+ fs.Close();
+ return ret;
+}