Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "dmMemory.h"
     18 #include "dmdefs.h"
     19 #include "dmt.hpp"
     20 #include "SyncML_PlugIn_WBXMLLog.H"
     21 #include "dmtRWPlugin.hpp"
     22 #include "xpl_File.h"
     23 #include "dm_uri_utils.h"
     24 #include "dm_tree_class.H"
     25 
     26 #ifdef TEST_DM_RECOVERY
     27 #include <unistd.h>
     28 extern char power_fail_point[];
     29 #endif
     30 
     31 DmtRWPluginTree::DmtRWPluginTree()
     32 {
     33     fpLog = NULL;
     34     log = NULL;
     35     m_Playback = FALSE;
     36    m_strLogPath = NULL;
     37    m_ESNDirty = FALSE;
     38    m_bIsAtomic = FALSE;
     39 }
     40 
     41 DmtRWPluginTree::~DmtRWPluginTree()
     42 {
     43     if(fpLog != NULL)
     44         delete fpLog;
     45 
     46     if(this->log != NULL)
     47         delete this->log;
     48 }
     49 
     50 SYNCML_DM_RET_STATUS_T
     51 DmtRWPluginTree::setLogFileHandle(DMFileHandler* fileHandle)
     52 {
     53     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
     54     if(this->log != NULL)
     55     {
     56         delete this->log;
     57         this->log = NULL;
     58     }
     59     if(fpLog != NULL)
     60       delete fpLog;
     61 
     62     fpLog = fileHandle;
     63     this->log = new SyncML_PlugIn_WBXMLLog(this,(CPCHAR) m_strRootPath.c_str());
     64     if(this->log != NULL)
     65         dm_stat = this->log->setLogFileHandle(fpLog);
     66     else
     67         dm_stat = SYNCML_DM_FAIL;
     68 
     69     return dm_stat;
     70 }
     71 
     72 SYNCML_DM_RET_STATUS_T
     73 DmtRWPluginTree::InitLog ()
     74 {
     75     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
     76     if(this->log  != NULL)
     77         return SYNCML_DM_SUCCESS;
     78 
     79     if(m_strLogPath == NULL)
     80     {
     81         DMString file_name;
     82         char uniqueStr[20];
     83         XPL_CLK_LONG_CLOCK_T curTime = XPL_CLK_GetClockMs();
     84         DmSprintf(uniqueStr, "%lld", curTime);
     85         if(uniqueStr[0] == '-')
     86            uniqueStr[0]='L';
     87 
     88      dmTreeObj.GetWritableFileSystemFullPath( m_strLogPath );
     89 
     90         CPCHAR pT = m_strLogPath.c_str();
     91         if (pT[m_strLogPath.length()-1] != '/')
     92           m_strLogPath += "/";
     93 
     94         XPL_FS_MkDir(m_strLogPath);
     95         m_strLogPath += uniqueStr;
     96         m_strLogPath +=  ".log";
     97     }
     98     this->log = new SyncML_PlugIn_WBXMLLog(this,(CPCHAR) m_strRootPath.c_str());
     99     if(this->log == NULL)
    100        return SYNCML_DM_FAIL;
    101     dm_stat = this->log->InitLog(m_strLogPath.c_str());
    102     if(dm_stat != SYNCML_DM_SUCCESS)
    103             return dm_stat;
    104 
    105     return SYNCML_DM_SUCCESS;
    106 }
    107 
    108 SYNCML_DM_RET_STATUS_T
    109 DmtRWPluginTree::LogCommand(SYNCML_DM_PLUGIN_COMMAND_T type,
    110                                  CPCHAR pbURI,
    111                                  SYNCML_DM_PLUGIN_COMMAND_ATTRIBUTE_T attribute,
    112                                  const DmtNode * inNode)
    113 {
    114     if(m_Playback == TRUE)
    115        return SYNCML_DM_SUCCESS;
    116 
    117     SYNCML_DM_RET_STATUS_T  dm_stat = InitLog();
    118     if(this->log == NULL)
    119        return dm_stat;
    120 
    121     switch ( type )
    122     {
    123        case SYNCML_DM_PLUGIN_ADD:
    124            dm_stat = log->logCommand(SYNCML_DM_PLUGIN_DELETE, pbURI, attribute, inNode);
    125            break;
    126 
    127        case SYNCML_DM_PLUGIN_REPLACE:
    128            dm_stat = log->logCommand(SYNCML_DM_PLUGIN_REPLACE, pbURI, attribute, inNode);
    129            break;
    130 
    131        case SYNCML_DM_PLUGIN_DELETE:
    132            if(DmStrlen(pbURI) != 0)
    133               log->logCommand(SYNCML_DM_PLUGIN_ADD_CHILD, pbURI, attribute, inNode);
    134            dm_stat = log->logCommand(SYNCML_DM_PLUGIN_ADD, pbURI, attribute, inNode);
    135            break;
    136     }
    137     return dm_stat;
    138 }
    139 
    140 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Verify()
    141 {
    142    //@@@TODO
    143     return SYNCML_DM_SUCCESS;
    144 }
    145 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateInteriorNodeInternal( CPCHAR path, PDmtNode& ptrCreatedNode, const DMStringVector & childNodeNames)
    146 {
    147     PDmtRWPluginNode pNode;
    148     SYNCML_DM_RET_STATUS_T dm_stat;
    149 
    150     pNode = new DmtRWPluginNode();
    151     if ( pNode == NULL )
    152         return SYNCML_DM_DEVICE_FULL;
    153 
    154     dm_stat = pNode->Init(this, path, childNodeNames);
    155     if ( dm_stat != SYNCML_DM_SUCCESS )
    156         return dm_stat;
    157 
    158     dm_stat = this->SetNode(path, PDmtNode(pNode));
    159     if ( dm_stat == SYNCML_DM_SUCCESS )
    160         dm_stat = GetNode( path, ptrCreatedNode );
    161 
    162     return dm_stat;
    163 }
    164 
    165 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateLeafNodeInternal( CPCHAR path, PDmtNode& ptrCreatedNode, const DmtData& value )
    166 {
    167     PDmtRWPluginNode pNode;
    168     SYNCML_DM_RET_STATUS_T dm_stat;
    169 
    170     pNode=new DmtRWPluginNode();
    171     if ( pNode == NULL )
    172         return SYNCML_DM_DEVICE_FULL;
    173 
    174      dm_stat = pNode->Init(this, path, value);
    175     if ( dm_stat != SYNCML_DM_SUCCESS )
    176         return dm_stat;
    177 
    178     dm_stat = this->SetNode(path, PDmtNode(pNode));
    179     if ( dm_stat == SYNCML_DM_SUCCESS )
    180         dm_stat = GetNode( path, ptrCreatedNode );
    181 
    182     return dm_stat;
    183 }
    184 
    185 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::DeleteSubTree( PDmtNode ptrNode)
    186 {
    187     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    188     DMString nodePath;
    189     if(!ptrNode->IsLeaf())
    190     {
    191         DMVector<PDmtNode> oChildren;
    192         dm_stat = ptrNode->GetChildNodes( oChildren );
    193         if ( dm_stat != SYNCML_DM_SUCCESS )
    194             return dm_stat;
    195 
    196         for ( int i = 0; i < oChildren.size(); i++ )
    197         {
    198             if (oChildren[i]->IsLeaf() )
    199             {
    200                 dm_stat = oChildren[i]->GetPath(nodePath);
    201                 if ( dm_stat == SYNCML_DM_SUCCESS )
    202                 {
    203                     dm_stat = this->RemoveNode(nodePath);
    204                     oChildren[i] = NULL;
    205                 }
    206             }
    207             else
    208                dm_stat =DeleteSubTree(oChildren[i]);
    209 
    210             if( dm_stat != SYNCML_DM_SUCCESS)
    211                 return dm_stat;
    212         }
    213   }
    214 
    215   dm_stat = ptrNode->GetPath(nodePath);
    216   if ( dm_stat == SYNCML_DM_SUCCESS )
    217     dm_stat = this->RemoveNode(nodePath);
    218   ptrNode = NULL;
    219 
    220   return dm_stat;
    221 
    222 }
    223 
    224 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::DeleteNode( CPCHAR path )
    225 {
    226     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    227     PDmtNode ptrNode;
    228 
    229     dm_stat = GetNode( path, ptrNode);
    230     if ( dm_stat != SYNCML_DM_SUCCESS)
    231         return dm_stat;
    232 
    233 #ifdef LOB_SUPPORT
    234     // Create temporary storage for ESN
    235     dm_stat = BackupESNdata(path);
    236     if ( dm_stat != SYNCML_DM_SUCCESS)
    237         return dm_stat;
    238 
    239 #endif
    240 
    241     dm_stat = LogCommand(SYNCML_DM_PLUGIN_DELETE, path, SYNCML_DM_PLUGIN_COMMAND_ON_NODE, ptrNode);
    242     if ( dm_stat != SYNCML_DM_SUCCESS)
    243         return dm_stat;
    244 
    245     dm_stat = DeleteSubTree(ptrNode);
    246     if ( dm_stat != SYNCML_DM_SUCCESS)
    247         return dm_stat;
    248 
    249     // Is it the root node ?
    250     if(DmStrlen(path) == 0)
    251         return dm_stat;
    252 
    253     DMString strURI;
    254     DMString strKey;
    255     DmParseURI( path, strURI, strKey );
    256 
    257 
    258     DMStringVector oChildren;
    259     dm_stat = this->GetChildNodeNames(strURI.c_str(), oChildren);
    260     if ( dm_stat != SYNCML_DM_SUCCESS)
    261         return dm_stat;
    262 
    263     // Is the plugin root node?
    264     if(strURI.length() == 0)
    265     {
    266         for (INT32 i = 0; i < oChildren.size(); i++ )
    267         {
    268             if (!DmStrcmp(oChildren[i].c_str() , path))
    269                 oChildren.remove(i);
    270         }
    271     }
    272     else
    273     {
    274         for ( INT32 i = 0; i < oChildren.size(); i++ )
    275         {
    276             if (!DmStrcmp(oChildren[i].c_str() , strKey.c_str()))
    277                 oChildren.remove(i);
    278         }
    279     }
    280 
    281       // Remove link to parent node
    282     dm_stat = GetNode( strURI.c_str(), ptrNode);
    283     if ( dm_stat != SYNCML_DM_SUCCESS)
    284         return dm_stat;
    285 
    286 
    287     DmtData m_value;
    288     dm_stat = m_value.SetNodeValue(oChildren);
    289 
    290     if ( dm_stat != SYNCML_DM_SUCCESS)
    291         return dm_stat;
    292 
    293     // Turn off logging temporarilly
    294     BOOLEAN needLogging= m_Playback;
    295     m_Playback = TRUE;
    296     dm_stat = ptrNode->SetValue(m_value);
    297     m_Playback = needLogging;
    298 
    299     return dm_stat;
    300 }
    301 //--------------------------------------------------------------------------------------------
    302 // FUNCTION        : DmtRWPluginNode::RemoveNode
    303 // DESCRIPTION     : Remove a node from memory
    304 // ARGUMENTS PASSED:
    305 //
    306 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
    307 //
    308 //--------------------------------------------------------------------------------------------
    309 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::RemoveNode(CPCHAR path)
    310 {
    311     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    312     PDmtNode ptrNode;
    313 
    314     dm_stat = GetNode( path, ptrNode);
    315     if ( dm_stat != SYNCML_DM_SUCCESS)
    316         return dm_stat;
    317 #ifdef LOB_SUPPORT
    318    if(ptrNode->IsExternalStorageNode())
    319   {
    320       PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
    321       dm_stat = pRWNode->Delete();
    322      if ( dm_stat != SYNCML_DM_SUCCESS)
    323          return dm_stat;
    324   }
    325 #endif
    326   return DmtPluginTree::RemoveNode(path);
    327 
    328 }
    329 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::RenameNode( CPCHAR path, CPCHAR szNewNodeName )
    330 {
    331     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    332     PDmtNode ptrNode;
    333 
    334     dm_stat = GetNode( path, ptrNode);
    335     if ( dm_stat != SYNCML_DM_SUCCESS)
    336         return dm_stat;
    337 
    338     PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
    339 
    340     return pRWNode->Rename(szNewNodeName);
    341 }
    342 
    343 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::LinkToParentNode( CPCHAR path)
    344 {
    345     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    346     DMString strURI;
    347     DMString strKey;
    348     PDmtNode ptrNode;
    349     DmParseURI( path, strURI, strKey );
    350     DMStringVector oChildren;
    351 
    352     dm_stat = this->GetChildNodeNames( strURI.c_str(), oChildren);
    353     if ( dm_stat != SYNCML_DM_SUCCESS)
    354         return dm_stat;
    355 
    356     if(strURI.length() != 0)
    357         oChildren.push_back(strKey.c_str());
    358     else
    359         oChildren.push_back(path);
    360 
    361     DmtData m_value;
    362     dm_stat = m_value.SetNodeValue(oChildren);
    363 
    364     if ( dm_stat != SYNCML_DM_SUCCESS)
    365         return dm_stat;
    366 
    367 
    368     dm_stat = GetNode( strURI.c_str(), ptrNode);
    369     if ( dm_stat != SYNCML_DM_SUCCESS)
    370         return dm_stat;
    371 
    372     // Turn off logging temporarilly
    373     BOOLEAN needLogging= m_Playback;
    374     m_Playback = TRUE;
    375     dm_stat = ptrNode->SetValue(m_value);
    376     m_Playback = needLogging;
    377     return dm_stat;
    378 
    379  }
    380 #ifdef LOB_SUPPORT
    381 //--------------------------------------------------------------------------------------------
    382 // FUNCTION        : DmtRWPluginTree::BackupESNdata
    383 // DESCRIPTION     : Create temporary storage for ESN
    384 // ARGUMENTS PASSED:
    385 //
    386 // RETURN VALUE    :
    387 //--------------------------------------------------------------------------------------------
    388 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::BackupESNdata( CPCHAR path)
    389 {
    390   SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    391   PDmtNode ptrNode;
    392 
    393   dm_stat = GetNode( path, ptrNode);
    394   if ( dm_stat != SYNCML_DM_SUCCESS)
    395       return dm_stat;
    396 
    397  if (ptrNode->IsLeaf())
    398 {
    399      if(ptrNode->IsExternalStorageNode())
    400      {
    401          PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
    402 
    403         // Backup file already exist?
    404         if(pRWNode->GetESNBackupFileName() != NULL)
    405             return SYNCML_DM_SUCCESS;
    406 
    407         // Backup ESN data
    408          dm_stat = pRWNode->BackupESNData();
    409      }
    410  }
    411  else
    412  {
    413         DMStringVector mapNodeNames;
    414       DMString strVal;
    415 
    416         dm_stat = GetChildNodeNames( path, mapNodeNames );
    417 
    418         if ( dm_stat != SYNCML_DM_SUCCESS )
    419            return dm_stat;
    420 
    421         for ( int i = 0; i < mapNodeNames.size(); i++ )
    422         {
    423         DMString strVal = path;
    424         // Is root node?
    425         if(strVal.length() != 0)
    426               strVal += "/";
    427         // Construct child node name
    428                strVal += mapNodeNames[i];
    429         dm_stat = BackupESNdata(strVal.c_str());
    430             if ( dm_stat != SYNCML_DM_SUCCESS )
    431             return dm_stat;
    432         }
    433     }
    434     return dm_stat;
    435 }
    436 //--------------------------------------------------------------------------------------------
    437 // FUNCTION        : DmtRWPluginTree::CommitESN
    438 // DESCRIPTION     : Commit changes for ESN
    439 // ARGUMENTS PASSED:
    440 //
    441 // RETURN VALUE    :
    442 //--------------------------------------------------------------------------------------------
    443 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CommitESN( CPCHAR path)
    444 {
    445   SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    446   PDmtNode ptrNode;
    447 
    448   // Any ESN data modified?
    449   if(!m_ESNDirty)
    450       return dm_stat;
    451 
    452   dm_stat = GetNode( path, ptrNode);
    453   if ( dm_stat != SYNCML_DM_SUCCESS)
    454       return dm_stat;
    455 
    456  if (ptrNode->IsLeaf())
    457 {
    458      if(ptrNode->IsExternalStorageNode())
    459      {
    460          PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
    461 
    462         // Backup ESN data
    463          dm_stat = pRWNode->Commit();
    464      }
    465  }
    466  else
    467  {
    468         DMStringVector mapNodeNames;
    469       DMString strVal;
    470 
    471         dm_stat = GetChildNodeNames( path, mapNodeNames );
    472 
    473         if ( dm_stat != SYNCML_DM_SUCCESS )
    474            return dm_stat;
    475 
    476         for ( int i = 0; i < mapNodeNames.size(); i++ )
    477         {
    478         DMString strVal = path;
    479         // Is root node?
    480         if(strVal.length() != 0)
    481                   strVal += "/";
    482         // Construct child node name
    483                strVal += mapNodeNames[i];
    484         dm_stat = CommitESN(strVal.c_str());
    485             if ( dm_stat != SYNCML_DM_SUCCESS )
    486             return dm_stat;
    487         }
    488     }
    489     return dm_stat;
    490 }
    491 //--------------------------------------------------------------------------------------------
    492 // FUNCTION        : DmtRWPluginTree::IsESNSetComplete
    493 // DESCRIPTION     : Check if all the ESN setting are done
    494 // ARGUMENTS PASSED:
    495 //
    496 // RETURN VALUE    :
    497 //--------------------------------------------------------------------------------------------
    498 BOOLEAN DmtRWPluginTree::IsESNSetComplete(CPCHAR pbURI)
    499 {
    500   SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    501   PDmtNode ptrNode;
    502   // Any ESN data modified?
    503   if(!m_ESNDirty)
    504       return TRUE;
    505 
    506   dm_stat = GetNode( pbURI, ptrNode);
    507   if ( dm_stat != SYNCML_DM_SUCCESS)
    508       return TRUE;
    509 
    510  if (ptrNode->IsLeaf())
    511 {
    512      PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
    513      if(ptrNode->IsExternalStorageNode() && !pRWNode->IsESNSetComplete())
    514          return FALSE;
    515      else
    516          return TRUE;
    517  }
    518  else
    519  {
    520         DMStringVector mapNodeNames;
    521       DMString strVal;
    522 
    523         dm_stat = GetChildNodeNames( pbURI, mapNodeNames );
    524 
    525         if ( dm_stat != SYNCML_DM_SUCCESS )
    526            return TRUE;
    527 
    528         for ( int i = 0; i < mapNodeNames.size(); i++ )
    529         {
    530         DMString strVal = pbURI;
    531               strVal += "/";
    532         // Construct child node name
    533                strVal += mapNodeNames[i];
    534         if(IsESNSetComplete(strVal.c_str()) == FALSE)
    535             return FALSE;
    536         }
    537     }
    538     return TRUE;
    539 }
    540 #endif
    541 
    542 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateLeafNodeInternal( CPCHAR path,
    543                                                              PDmtNode& ptrCreatedNode,
    544                                                              const DmtData& value ,
    545                                                              BOOLEAN isESN)
    546 {
    547     PDmtRWPluginNode pNode;
    548     SYNCML_DM_RET_STATUS_T dm_stat;
    549 
    550     pNode=new DmtRWPluginNode();
    551     if ( pNode == NULL )
    552         return SYNCML_DM_DEVICE_FULL;
    553 
    554      dm_stat = pNode->Init(this, path, value, isESN);
    555     if ( dm_stat != SYNCML_DM_SUCCESS )
    556         return dm_stat;
    557 
    558     dm_stat = this->SetNode(path, PDmtNode(pNode));
    559     if ( dm_stat == SYNCML_DM_SUCCESS )
    560         dm_stat = GetNode( path, ptrCreatedNode );
    561 
    562     return dm_stat;
    563 }
    564 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateLeafNode(CPCHAR path,
    565                               PDmtNode& ptrCreatedNode,
    566                               const DmtData& value ,
    567                               BOOLEAN isESN)
    568 {
    569     SYNCML_DM_RET_STATUS_T dm_stat;
    570 
    571     dm_stat = LogCommand(SYNCML_DM_PLUGIN_ADD, path, SYNCML_DM_PLUGIN_COMMAND_ON_NODE, NULL);
    572     if ( dm_stat != SYNCML_DM_SUCCESS)
    573         return dm_stat;
    574 
    575     dm_stat = this ->CreateLeafNodeInternal(path, ptrCreatedNode, value, isESN );
    576     if (dm_stat != SYNCML_DM_SUCCESS)
    577     {
    578         if ( dm_stat == SYNCML_DM_FEATURE_NOT_SUPPORTED )
    579             return SYNCML_DM_SUCCESS;
    580         else
    581             return dm_stat;
    582     }
    583 
    584     dm_stat = LinkToParentNode(path);
    585     return dm_stat;
    586 }
    587 
    588 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateLeafNode( CPCHAR path,
    589                                                             PDmtNode& ptrCreatedNode,
    590                                                             const DmtData& value )
    591 {
    592     SYNCML_DM_RET_STATUS_T dm_stat;
    593 
    594     dm_stat = LogCommand(SYNCML_DM_PLUGIN_ADD, path, SYNCML_DM_PLUGIN_COMMAND_ON_NODE, NULL);
    595     if ( dm_stat != SYNCML_DM_SUCCESS)
    596         return dm_stat;
    597 
    598     dm_stat = this ->CreateLeafNodeInternal(path, ptrCreatedNode, value );
    599     if (dm_stat != SYNCML_DM_SUCCESS)
    600     {
    601         if ( dm_stat == SYNCML_DM_FEATURE_NOT_SUPPORTED )
    602             return SYNCML_DM_SUCCESS;
    603         else
    604             return dm_stat;
    605     }
    606 
    607     dm_stat = LinkToParentNode(path);
    608     return dm_stat;
    609 }
    610 
    611 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateInteriorNode( CPCHAR path, PDmtNode& ptrCreatedNode )
    612 {
    613     SYNCML_DM_RET_STATUS_T dm_stat;
    614     dm_stat = LogCommand(SYNCML_DM_PLUGIN_ADD, path, SYNCML_DM_PLUGIN_COMMAND_ON_NODE, NULL);
    615     if ( dm_stat != SYNCML_DM_SUCCESS)
    616         return dm_stat;
    617 
    618     DMStringVector oChildren;
    619     dm_stat  = this->CreateInteriorNodeInternal(path, ptrCreatedNode, oChildren);
    620     if (dm_stat != SYNCML_DM_SUCCESS)
    621     {
    622         if ( dm_stat == SYNCML_DM_FEATURE_NOT_SUPPORTED )
    623             return SYNCML_DM_SUCCESS;
    624         else
    625             return dm_stat;
    626     }
    627 
    628     dm_stat = LinkToParentNode(path);
    629     return dm_stat;
    630 }
    631 
    632 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Begin()
    633 {
    634   #ifdef DM_ATOMIC_SUPPORTED
    635   SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
    636     m_bIsAtomic = TRUE;
    637     ret_stat = this->Flush();
    638     return ret_stat;
    639   #else
    640     return SYNCML_DM_FEATURE_NOT_SUPPORTED;
    641   #endif
    642   }
    643 
    644 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Commit()
    645 {
    646    #ifdef DM_ATOMIC_SUPPORTED
    647      SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
    648 
    649     ret_stat = this->Flush();
    650     m_bIsAtomic = FALSE;
    651     return ret_stat;
    652    #else
    653     return SYNCML_DM_FEATURE_NOT_SUPPORTED;
    654    #endif
    655 
    656 }
    657 
    658 BOOLEAN DmtRWPluginTree::IsAtomic() const
    659 {
    660     return m_bIsAtomic;
    661 }
    662 
    663 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Flush()
    664 {
    665     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    666 #ifdef LOB_SUPPORT
    667     // Verify if all ESN setting are complete.
    668     if(IsESNSetComplete("") ==  FALSE)
    669      return     SYNCML_DM_ESN_SET_NOT_COMPLETE;
    670 #endif
    671     if(this->log != NULL)
    672     {
    673       this->log->RemoveLog();
    674 
    675         delete this->log;
    676         this->log = NULL;
    677 
    678     }
    679    if(m_strLogPath != NULL)
    680        m_strLogPath = NULL;
    681 
    682 #ifdef LOB_SUPPORT
    683     // Commit all  ESN changes.
    684      dm_stat = CommitESN("");
    685      m_ESNDirty = FALSE;
    686 #endif
    687     return dm_stat;
    688 }
    689 
    690 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Rollback()
    691 {
    692    #ifdef DM_ATOMIC_SUPPORTED
    693     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    694     m_Playback = TRUE;
    695 
    696 #ifdef TEST_DM_RECOVERY
    697     if ((power_fail_point != NULL) && (DmStrcmp(power_fail_point, "PLUGIN_PF2") == 0))
    698     {
    699         printf("Type Ctrl-C to simulate Power Fail ...\n");
    700         sleep(30);
    701     }
    702 #endif
    703     if(this->log != NULL)
    704     {
    705     if(fpLog == NULL)
    706             dm_stat = log->playLog(m_strLogPath.c_str());
    707     else
    708     {    dm_stat = log->playLog();
    709         this->log->RemoveLog();
    710         fpLog = NULL;
    711     }
    712         delete this->log;
    713         this->log = NULL;
    714     }
    715    if(m_strLogPath != NULL)
    716      m_strLogPath = NULL;
    717 
    718 #ifdef TEST_DM_RECOVERY
    719     if ((power_fail_point != NULL) && (DmStrcmp(power_fail_point, "PLUGIN_PF3") == 0))
    720     {
    721         printf("Type Ctrl-C to simulate Power Fail ...\n");
    722         sleep(30);
    723     }
    724 #endif
    725 
    726     m_Playback = FALSE;
    727     m_ESNDirty = FALSE;
    728     m_bIsAtomic = FALSE;
    729     m_oAddedNodes.clear();
    730     return dm_stat;
    731    #else
    732    return SYNCML_DM_FEATURE_NOT_SUPPORTED;
    733    #endif
    734 }
    735 
    736 
    737 BOOLEAN DmtRWPluginTree::IsPlaybackMode()
    738 {
    739     return m_Playback;
    740 }
    741 
    742 SYNCML_DM_RET_STATUS_T DmtRWPluginTree::SetPlaybackMode(boolean bPlayback)
    743 {
    744      m_Playback = bPlayback;
    745      return SYNCML_DM_SUCCESS;
    746 }
    747 
    748 
    749 DmtRWPluginNode::~DmtRWPluginNode()
    750 {
    751 }
    752 
    753 DmtRWPluginNode::DmtRWPluginNode()
    754 {
    755 #ifdef LOB_SUPPORT
    756   m_LobComplete = TRUE;
    757   m_LobDirty = FALSE;
    758   m_LobLogging = FALSE;
    759   abStorageName = NULL;
    760 #endif
    761 }
    762 
    763 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetTitle( CPCHAR szTitle )
    764 {
    765     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    766     PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
    767 
    768     dm_stat = ptrTree->LogCommand(SYNCML_DM_PLUGIN_REPLACE,
    769                                   m_strPath.c_str(),
    770                                   SYNCML_DM_PLUGIN_COMMAND_ON_TITLE_PROPERTY,
    771                                   (const DmtNode*)this);
    772 
    773     if ( dm_stat != SYNCML_DM_SUCCESS)
    774         return dm_stat;
    775 
    776     DmtAttributes oAttr;
    777     dm_stat =this->GetAttributes( oAttr );
    778 
    779     if ( dm_stat != SYNCML_DM_SUCCESS)
    780         return dm_stat;
    781 
    782     return m_oAttr.SetTitle(szTitle);
    783 }
    784 
    785 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetValueInternal( const DmtData& value )
    786 {
    787     m_oData = value;
    788     return SYNCML_DM_SUCCESS;
    789 }
    790 
    791 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetValue( const DmtData& value )
    792 {
    793     XPL_LOG_DM_PLG_Debug(("Enter DmtRWPluginNode::SetValue..."));
    794     PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
    795     SYNCML_DM_RET_STATUS_T dm_stat;
    796 
    797     dm_stat= ptrTree->LogCommand(SYNCML_DM_PLUGIN_REPLACE,
    798                                  m_strPath.c_str(),
    799                                  SYNCML_DM_PLUGIN_COMMAND_ON_NODE,
    800                                 (const DmtNode *)this);
    801     XPL_LOG_DM_PLG_Debug(("LogCommand returns dm_stat=%d", dm_stat));
    802 
    803     if(dm_stat == SYNCML_DM_SUCCESS)
    804     {
    805     INT32 dataSize;
    806       m_oData = value;
    807 
    808       // Get data size
    809       dm_stat = m_oData.GetSize(dataSize);
    810     XPL_LOG_DM_PLG_Debug(("DmtRWPluginNode::SetValue m_oData.getSize() returns dataSize=%d dm_stat=%d", dataSize, dm_stat));
    811       if ( dm_stat != SYNCML_DM_SUCCESS )
    812           return dm_stat;
    813 
    814     XPL_LOG_DM_PLG_Debug(("calling m_oAttr.SetSize(%d)", dataSize));
    815       m_oAttr.SetSize(dataSize);
    816     }
    817 
    818     XPL_LOG_DM_PLG_Debug(("DmtRWPluginNode::SetValue returns dm_stat=%d", dm_stat));
    819     return dm_stat;
    820 }
    821 
    822 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::Rename( CPCHAR szNewName )
    823 {
    824     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    825     PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
    826 
    827     DMString strURI;
    828     DMString strKey;
    829     DmParseURI( m_strPath.c_str(), strURI, strKey );
    830 
    831     DMString strNewURI = strURI;
    832     if(strNewURI.length() != 0)
    833         strNewURI += "/";
    834     strNewURI += szNewName;
    835 
    836     dm_stat = ptrTree->LogCommand(SYNCML_DM_PLUGIN_REPLACE,
    837                                   (CPCHAR)strNewURI.c_str(),
    838                                   SYNCML_DM_PLUGIN_COMMAND_ON_NAME_PROPERTY,
    839                                   (const DmtNode*)this);
    840 
    841     if ( dm_stat != SYNCML_DM_SUCCESS)
    842         return dm_stat;
    843 
    844     DMStringVector oChildren;
    845 
    846     dm_stat = m_ptrTree->GetChildNodeNames( strURI.c_str(), oChildren);
    847     if ( dm_stat != SYNCML_DM_SUCCESS)
    848         return dm_stat;
    849 
    850     // Is the plugin root node?
    851     if(strURI.length() == 0)
    852     {
    853         for ( INT32 i = 0; i < oChildren.size(); i++ )
    854         {
    855             if (!DmStrcmp(oChildren[i].c_str() , m_strPath.c_str()))
    856             {
    857                 oChildren.remove(i);
    858                 break;
    859             }
    860         }
    861     }
    862     else
    863     {
    864         for ( INT32 i = 0; i < oChildren.size(); i++ )
    865         {
    866             if (!DmStrcmp(oChildren[i].c_str() , strKey.c_str()))
    867             {
    868                 oChildren.remove(i);
    869                 break;
    870             }
    871         }
    872     }
    873 
    874     oChildren.push_back(szNewName);
    875     PDmtNode ptrParentNode;
    876     DmtData m_value;
    877 
    878     dm_stat = m_value.SetNodeValue(oChildren);
    879     if ( dm_stat != SYNCML_DM_SUCCESS)
    880         return dm_stat;
    881 
    882     dm_stat = m_ptrTree->GetNode( strURI.c_str(), ptrParentNode);
    883     if ( dm_stat != SYNCML_DM_SUCCESS)
    884         return dm_stat;
    885 
    886     PDmtRWPluginNode pRWParentNode = (DmtRWPluginNode *) ((DmtNode *)ptrParentNode);
    887 
    888     DmtData oData;
    889     dm_stat = pRWParentNode->GetValue( oData );
    890     if ( dm_stat != SYNCML_DM_SUCCESS)
    891         return dm_stat;
    892 
    893     // Turn off logging temporarilly
    894     BOOLEAN needLogging= ptrTree->IsPlaybackMode();
    895     ptrTree->SetPlaybackMode(TRUE);
    896     dm_stat = pRWParentNode->SetValue(m_value);
    897     ptrTree->SetPlaybackMode(needLogging);
    898 
    899     if ( dm_stat != SYNCML_DM_SUCCESS)
    900         return dm_stat;
    901 
    902     dm_stat = pRWParentNode->GetValue( oData );
    903 
    904     m_strName = szNewName;
    905     if ( szNewName && szNewName[0] )
    906     {
    907         if ( m_strName == NULL )
    908             return SYNCML_DM_DEVICE_FULL;
    909     }
    910 
    911     DmtAttributes oAttr;
    912     dm_stat = this->GetAttributes( oAttr );
    913     if ( dm_stat != SYNCML_DM_SUCCESS)
    914         return dm_stat;
    915 
    916     dm_stat = m_oAttr.SetName(szNewName);
    917 
    918     if (dm_stat != SYNCML_DM_SUCCESS)
    919         return dm_stat;
    920 
    921     dm_stat = RenameChildNodes(strURI.c_str(), szNewName);
    922     return dm_stat;
    923 }
    924 
    925 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::RenameChildNodes( CPCHAR szParentPath, CPCHAR szNodeName )
    926 {
    927     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    928     DMString strURI = szParentPath;
    929 
    930     if(strURI.length() != 0)
    931         strURI += "/";
    932     strURI += szNodeName;
    933 
    934     dm_stat = m_ptrTree->RemoveNode(m_strPath.c_str());
    935     if ( dm_stat != SYNCML_DM_SUCCESS)
    936         return dm_stat;
    937 
    938 
    939     dm_stat = m_ptrTree->SetNode(strURI.c_str(), this);
    940     if ( dm_stat != SYNCML_DM_SUCCESS)
    941         return dm_stat;
    942 
    943     if ( m_bLeaf )
    944     {
    945         m_strPath = strURI;
    946         return SYNCML_DM_SUCCESS;
    947     }
    948 
    949 
    950     DMStringVector oChildren;
    951     dm_stat = m_ptrTree->GetChildNodeNames( strURI.c_str(), oChildren);
    952     if ( dm_stat != SYNCML_DM_SUCCESS)
    953         return dm_stat;
    954 
    955     for ( int i = 0; i < oChildren.size(); i++ )
    956     {
    957         DMString strChildPath = m_strPath;
    958 
    959         if (strChildPath.length() !=0)
    960             strChildPath += "/";
    961 
    962         strChildPath += oChildren[i];
    963 
    964         PDmtNode ptrNode;
    965 
    966         dm_stat = m_ptrTree->GetNode( strChildPath.c_str(), ptrNode );
    967         if ( dm_stat != SYNCML_DM_SUCCESS)
    968             return dm_stat;
    969 
    970         PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
    971 
    972         dm_stat = pRWNode->RenameChildNodes(strURI.c_str(), oChildren[i].c_str());
    973         if ( dm_stat != SYNCML_DM_SUCCESS)
    974             return dm_stat;
    975     }
    976     m_strPath = strURI;
    977 
    978     return dm_stat;
    979 }
    980 
    981 #ifdef LOB_SUPPORT
    982 //--------------------------------------------------------------------------------------------
    983 // FUNCTION        : DmtRWPluginNode::GetFirstChunk
    984 // DESCRIPTION     :
    985 // ARGUMENTS PASSED:
    986 //
    987 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
    988 //
    989 //--------------------------------------------------------------------------------------------
    990 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::GetFirstChunk(DmtDataChunk&  dmtChunkData)
    991 {
    992    // Only for ESN
    993     if(!m_bESN)
    994     return SYNCML_DM_COMMAND_NOT_ALLOWED;
    995     if(m_LobComplete == FALSE)
    996         return SYNCML_DM_ESN_SET_NOT_COMPLETE;
    997 
    998     return SYNCML_DM_SUCCESS;
    999 }
   1000 
   1001 //--------------------------------------------------------------------------------------------
   1002 // FUNCTION        : DmtRWPluginNode::GetNextChunk
   1003 // DESCRIPTION     :
   1004 // ARGUMENTS PASSED:
   1005 //
   1006 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
   1007 //
   1008 //--------------------------------------------------------------------------------------------
   1009 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::GetNextChunk(DmtDataChunk& dmtChunkData)
   1010 {
   1011   // Only for ESN
   1012    if(!m_bESN)
   1013      return SYNCML_DM_COMMAND_NOT_ALLOWED;
   1014     if(m_LobComplete == FALSE)
   1015         return SYNCML_DM_ESN_SET_NOT_COMPLETE;
   1016 
   1017     return SYNCML_DM_SUCCESS;
   1018 }
   1019 
   1020 //--------------------------------------------------------------------------------------------
   1021 // FUNCTION        : DmtRWPluginNode::SetFirstChunk
   1022 // DESCRIPTION     :
   1023 // ARGUMENTS PASSED:
   1024 //
   1025 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
   1026 //
   1027 //--------------------------------------------------------------------------------------------
   1028 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetFirstChunk(DmtDataChunk& dmtChunkData)
   1029 {
   1030   SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1031   PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
   1032   // Only for ESN
   1033    if(!m_bESN)
   1034        return SYNCML_DM_COMMAND_NOT_ALLOWED;
   1035 
   1036   // Need to log the command ?
   1037   if(!ptrTree->IsPlaybackMode())
   1038   {
   1039    if(!m_LobLogging)
   1040    {
   1041          dm_stat = BackupESNData();
   1042          if ( dm_stat != SYNCML_DM_SUCCESS)
   1043            return dm_stat;
   1044 
   1045           dm_stat = ptrTree->LogCommand(SYNCML_DM_PLUGIN_REPLACE,
   1046                                     m_strPath.c_str(),
   1047                                     SYNCML_DM_PLUGIN_COMMAND_ON_LOB_PROPERTY,
   1048                                     (const DmtNode*)this);
   1049 
   1050           if ( dm_stat != SYNCML_DM_SUCCESS)
   1051           return dm_stat;
   1052     m_LobLogging = TRUE;
   1053    }
   1054 
   1055   m_LobComplete = FALSE;
   1056   m_LobDirty = TRUE;
   1057   //Set flag in the plugin tree
   1058   ptrTree->SetESNDirty();
   1059   }
   1060   return dm_stat;
   1061 }
   1062 
   1063 //--------------------------------------------------------------------------------------------
   1064 // FUNCTION        : DmtRWPluginNode::SetNextChunk
   1065 // DESCRIPTION     :
   1066 // ARGUMENTS PASSED:
   1067 //
   1068 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
   1069 //
   1070 //--------------------------------------------------------------------------------------------
   1071 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetNextChunk(DmtDataChunk& dmtChunkData)
   1072 {
   1073   PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
   1074  // Only for ESN and SetFirstChunk() is invoked.
   1075  if(!m_bESN )
   1076       return SYNCML_DM_COMMAND_NOT_ALLOWED;
   1077  // Need to log the command ?
   1078  if(!ptrTree->IsPlaybackMode())
   1079  {
   1080      if(!m_LobDirty ||m_LobComplete)
   1081       return SYNCML_DM_INCOMPLETE_COMMAND;
   1082  }
   1083     return SYNCML_DM_SUCCESS;
   1084 }
   1085 
   1086 //--------------------------------------------------------------------------------------------
   1087 // FUNCTION        : DmtRWPluginNode::SetLastChunk
   1088 // DESCRIPTION     :
   1089 // ARGUMENTS PASSED:
   1090 //
   1091 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
   1092 //
   1093 //--------------------------------------------------------------------------------------------
   1094 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetLastChunk(DmtDataChunk& dmtChunkData)
   1095 {
   1096    PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
   1097   // Only for ESN and SetFirstChunk() is invoked.
   1098    if(!m_bESN )
   1099         return SYNCML_DM_COMMAND_NOT_ALLOWED;
   1100 
   1101    if(!ptrTree->IsPlaybackMode())
   1102    {
   1103        if(!m_LobDirty ||m_LobComplete)
   1104         return SYNCML_DM_INCOMPLETE_COMMAND;
   1105 
   1106        m_LobComplete = TRUE;
   1107    }
   1108    return SYNCML_DM_SUCCESS;
   1109 }
   1110 
   1111 //--------------------------------------------------------------------------------------------
   1112 // FUNCTION        : DmtRWPluginNode::Commit
   1113 // DESCRIPTION     : Commit changes for an ESN
   1114 // ARGUMENTS PASSED:
   1115 //
   1116 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
   1117 //
   1118 //--------------------------------------------------------------------------------------------
   1119 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::Commit()
   1120 {
   1121    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1122    // Only for ESN
   1123    if(m_bESN)
   1124    {
   1125        m_LobComplete = TRUE;
   1126        m_LobDirty = FALSE;
   1127        m_LobLogging = FALSE;
   1128     // Remove temporary storage file
   1129     if(abStorageName.length() != 0)
   1130     {
   1131         DMFileHandler sourceHandle(abStorageName);
   1132         dm_stat = sourceHandle.open(XPL_FS_FILE_RDWR);
   1133         if(dm_stat == SYNCML_DM_SUCCESS)
   1134                 sourceHandle.deleteFile();
   1135         abStorageName = NULL;
   1136     }
   1137    }
   1138    return SYNCML_DM_SUCCESS;
   1139 }
   1140 
   1141 //--------------------------------------------------------------------------------------------
   1142 // FUNCTION        : DmtRWPluginNode::Delete
   1143 // DESCRIPTION     : Delete the node
   1144 // ARGUMENTS PASSED:
   1145 //
   1146 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
   1147 //
   1148 //--------------------------------------------------------------------------------------------
   1149 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::Delete()
   1150 {
   1151    return SYNCML_DM_SUCCESS;
   1152 }
   1153 
   1154 //--------------------------------------------------------------------------------------------
   1155 // FUNCTION        : DmtRWPluginNode::BackupESNData
   1156 // DESCRIPTION     : Backup ESN data to temporary file
   1157 // ARGUMENTS PASSED:
   1158 //
   1159 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
   1160 //
   1161 //--------------------------------------------------------------------------------------------
   1162 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::BackupESNData()
   1163 {
   1164  SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1165  PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
   1166  DmtDataChunk chunkData;
   1167  UINT32 getLen;
   1168  UINT8 *bufp;
   1169 
   1170   if(!m_bESN || m_LobLogging)
   1171     return SYNCML_DM_SUCCESS;
   1172 
   1173   DmtAttributes oAttr;
   1174   dm_stat =this->GetAttributes( oAttr );
   1175   // Is the ESN empty
   1176   if(oAttr.GetSize() == 0)
   1177   {
   1178     abStorageName = NULL;
   1179     return SYNCML_DM_SUCCESS;
   1180   }
   1181 
   1182  // No internal file created yet
   1183  if(abStorageName.length() == 0) {
   1184        dm_stat = DMFileHandler::createTempESNFileName(abStorageName);
   1185        if(dm_stat != SYNCML_DM_SUCCESS)
   1186            return dm_stat;
   1187  }
   1188  DMFileHandler tempLogFileHandler(abStorageName);
   1189  dm_stat = tempLogFileHandler.open(XPL_FS_FILE_WRITE);
   1190  if(dm_stat != SYNCML_DM_SUCCESS)
   1191      return    SYNCML_DM_IO_FAILURE;
   1192 
   1193  // Allocate chunk buffer
   1194  if(chunkData.AllocateChunkBuffer() != SYNCML_DM_SUCCESS)
   1195     return  SYNCML_DM_DEVICE_FULL;
   1196 
   1197  dm_stat = GetFirstChunk(chunkData);
   1198  if( dm_stat != SYNCML_DM_SUCCESS)
   1199      return dm_stat;
   1200  chunkData.GetReturnLen(getLen);
   1201  chunkData.GetChunkData(&bufp);  // the chunk data is available
   1202 
   1203   while (true)
   1204  {
   1205       // Get the last chunk of data
   1206       if (getLen == 0)
   1207               break;
   1208       if(tempLogFileHandler.seek(XPL_FS_SEEK_END, 0) != SYNCML_DM_SUCCESS)
   1209       {
   1210          dm_stat =    SYNCML_DM_IO_FAILURE;
   1211         break;
   1212       }
   1213       if(tempLogFileHandler.write((CPCHAR)bufp, getLen) != SYNCML_DM_SUCCESS)
   1214       {
   1215         dm_stat =    SYNCML_DM_IO_FAILURE;
   1216         break;
   1217       }
   1218       dm_stat = GetNextChunk(chunkData);
   1219       if( dm_stat != SYNCML_DM_SUCCESS)
   1220           break;
   1221       chunkData.GetReturnLen(getLen);
   1222       chunkData.GetChunkData(&bufp);
   1223   }
   1224 
   1225   if(dm_stat != SYNCML_DM_SUCCESS)
   1226   {     tempLogFileHandler.deleteFile();
   1227       abStorageName = NULL;
   1228   }
   1229   else
   1230       tempLogFileHandler.close();
   1231 
   1232  //Set flag in the plugin tree
   1233  ptrTree->SetESNDirty();
   1234  return  dm_stat;
   1235 }
   1236 //--------------------------------------------------------------------------------------------
   1237 // FUNCTION        : DmtRWPluginNode::RestoreESNData
   1238 // DESCRIPTION     : Restore ESN data from temporary file
   1239 // ARGUMENTS PASSED:
   1240 //
   1241 // RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
   1242 //
   1243 //--------------------------------------------------------------------------------------------
   1244 SYNCML_DM_RET_STATUS_T DmtRWPluginNode::RestoreESNData( CPCHAR szBackupFileName )
   1245 {
   1246  SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1247  UINT32 totalSize;
   1248  DmtDataChunk chunkData;
   1249  int setLen = 0;
   1250  int offset = 0;
   1251  bool isFirstChunk = true;
   1252  bool isLastChunk = false;
   1253  UINT8 *bufp;
   1254 
   1255  if(!m_bESN )
   1256      return SYNCML_DM_SUCCESS;
   1257 
   1258  int chunksize = chunkData.GetChunkSize();
   1259 
   1260   m_LobComplete = TRUE;
   1261   m_LobDirty = FALSE;
   1262   m_LobLogging = FALSE;
   1263 
   1264   // No internal storage file
   1265   if(DmStrlen(szBackupFileName) == 0)
   1266   {
   1267       dm_stat = SetFirstChunk(chunkData);
   1268      if(dm_stat != SYNCML_DM_SUCCESS)
   1269          return dm_stat;
   1270       dm_stat = SetLastChunk(chunkData);
   1271      abStorageName = NULL;
   1272 
   1273      return dm_stat;
   1274   }
   1275 
   1276   if(!XPL_FS_Exist(szBackupFileName))
   1277     return SYNCML_DM_SUCCESS;
   1278 
   1279 
   1280  DMFileHandler tempFileHandler(szBackupFileName);
   1281  dm_stat = tempFileHandler.open(XPL_FS_FILE_RDWR);
   1282  if(dm_stat != SYNCML_DM_SUCCESS)
   1283      return    SYNCML_DM_IO_FAILURE;
   1284  totalSize = tempFileHandler.size();
   1285 
   1286  // Allocate chunk buffer
   1287  if(chunkData.AllocateChunkBuffer() != SYNCML_DM_SUCCESS)
   1288     return  SYNCML_DM_DEVICE_FULL;
   1289 
   1290  chunkData.GetChunkData(&bufp);  // the chunk data is available
   1291 
   1292 
   1293  while(!isLastChunk)
   1294  {     setLen =  totalSize- offset;
   1295      if(setLen > 0)
   1296      {
   1297          if(setLen > chunksize)
   1298              setLen = chunksize;
   1299      }
   1300      else
   1301          isLastChunk = true;
   1302 
   1303      if(tempFileHandler.seek(XPL_FS_SEEK_SET, offset) != SYNCML_DM_SUCCESS)
   1304          return  SYNCML_DM_IO_FAILURE;
   1305      if(tempFileHandler.read(bufp, setLen) != SYNCML_DM_SUCCESS)
   1306          return  SYNCML_DM_IO_FAILURE;
   1307 
   1308      dm_stat = chunkData.SetChunkData((const UINT8 *)bufp, setLen);
   1309      if(dm_stat != SYNCML_DM_SUCCESS)
   1310          return    dm_stat;
   1311 
   1312      if(isFirstChunk)
   1313      {
   1314          dm_stat = SetFirstChunk(chunkData);
   1315          isFirstChunk = false;
   1316      }
   1317      else
   1318      {     if(!isLastChunk)
   1319              dm_stat = SetNextChunk(chunkData);
   1320          else
   1321              dm_stat = SetLastChunk(chunkData);
   1322      }
   1323      if(dm_stat != SYNCML_DM_SUCCESS)
   1324          return    dm_stat;
   1325 
   1326         offset += setLen;
   1327     }
   1328 
   1329     totalSize = tempFileHandler.deleteFile();
   1330     abStorageName = NULL;
   1331     return dm_stat;
   1332 }
   1333 
   1334 #endif
   1335