Merge "Add new string get" into tizen_2.1
[platform/framework/native/appfw.git] / src / io / FIo_SecureFile.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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 /**
18  * @file        FIo_SecureFile.cpp
19  * @brief       This is the implementation file for _SecureFile class.
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/mman.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <time.h>
30 #include <limits.h>
31 #include <errno.h>
32 #include <new>
33 #include <unique_ptr.h>
34 #include <FBaseResult.h>
35 #include <FIoFile.h>
36 #include <FBase_StringConverter.h>
37 #include <FBase_NativeError.h>
38 #include <FBaseSysLog.h>
39 #include <FIo_FileImpl.h>
40 #include <FIo_NormalFile.h>
41 #include <FIo_SecureFile.h>
42 #include <FIo_SecureIoUtil.h>
43
44 using namespace std;
45 using namespace Tizen::Base;
46
47 namespace Tizen { namespace Io
48 {
49
50 _SecureFile::_SecureFile(void)
51         : __pNormalFile(null)
52         , __virtualFilePointer(0)
53         , __pKey(null)
54 {
55 }
56
57 _SecureFile::_SecureFile(bool read, bool write, bool truncate, bool append)
58         : __pNormalFile(null)
59         , __virtualFilePointer(0)
60         , __pKey(null)
61 {
62         _read = read;
63         _write = write;
64         _truncate = truncate;
65         _append = append;
66 }
67
68 _SecureFile::~_SecureFile(void)
69 {
70         delete __pNormalFile;
71         delete __pKey;
72 }
73
74 result
75 _SecureFile::Construct(const String& filePath, const char* pOpenMode, const ByteBuffer* pKeyBuffer)
76 {
77         SysAssertf(__pNormalFile == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
78
79         result r = E_SUCCESS;
80
81         SysTryReturnResult(NID_IO, !(pKeyBuffer && pKeyBuffer->GetRemaining() <= 0), E_INVALID_ARG,
82                                            "Invalid Key parameter");
83
84         unique_ptr< Tizen::Base::ByteBuffer > pKey(_SecureIoUtil::GetSecureKeyN(pKeyBuffer));
85         SysTryReturnResult(NID_IO, !(pKey == null || (pKey != null && pKey->GetRemaining() < ONE_BLOCK_SIZE)), E_INVALID_ARG, "Unable to generate key!");
86
87         unique_ptr< _NormalFile > pNormalFile(new (std::nothrow) _NormalFile());
88         SysTryReturnResult(NID_IO, pNormalFile != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
89
90         if (!_read)
91         {
92                 unique_ptr< char[] > pMode(new char[strlen(pOpenMode) + 2]);
93                 strcpy(pMode.get(), pOpenMode);
94                 strcat(pMode.get(), "+\0");
95                 r = pNormalFile->Construct(filePath, pMode.get());
96         }
97         else
98         {
99                 r = pNormalFile->Construct(filePath, pOpenMode);
100         }
101         SysSecureTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to open file (%ls) in openmode (%s).",
102                                  GetErrorMessage(r), filePath.GetPointer(), pOpenMode);
103
104         if (_append)
105         {
106                 r = _SecureIoUtil::GetDataLengh(pNormalFile.get(), &__virtualFilePointer);
107                 if (IsFailed(r))
108                 {
109                         if (r == E_END_OF_FILE)
110                         {
111                                 r = E_IO; //for security error
112                         }
113                         return r;
114                 }
115         }
116
117         if (!(_SecureIoUtil::IsEmpty(filePath)))
118         {
119                 Tizen::Io::_FlagState flag;
120
121                 r = _SecureIoUtil::CheckFlag(pNormalFile.get(), &flag);
122                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to check flags in file header.", GetErrorMessage(r));
123
124                 if (flag == FLAG_STATE_CVF_CTF)
125                 {
126                         r = _SecureIoUtil::DeleteBlockReplica(pNormalFile.get(), filePath);
127                         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to delete block replica of file.", GetErrorMessage(r));
128
129                         r = _SecureIoUtil::SetFlag(pNormalFile.get(), FLAG_STATE_CVF);
130                         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to set flags in file header.", GetErrorMessage(r));
131                 }
132                 else if (flag == FLAG_STATE_CTF)
133                 {
134                         r = _SecureIoUtil::RestoreCorruptBlock(pNormalFile.get(), filePath);
135                         SysTryReturnResult(NID_IO, !IsFailed(r), E_IO, "Failed to set flags in file header.");
136
137                         r = _SecureIoUtil::DeleteBlockReplica(pNormalFile.get(), filePath);
138                         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to delete block replica of file.", GetErrorMessage(r));
139
140                         r = _SecureIoUtil::SetFlag(pNormalFile.get(), FLAG_STATE_CVF);
141                         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to set flags in file header.", GetErrorMessage(r));
142                 }
143                 else if (flag == FLAG_STATE_CVF)
144                 {
145                         //Do Nothing
146                 }
147                 else
148                 {
149                         int readItems = 0;
150                         int dataLen = 0;
151                         r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_10_BYTES);
152                         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek file (%ls) in openMode (%s).",
153                                                  GetErrorMessage(r), filePath.GetPointer(), pOpenMode);
154
155                         readItems = pNormalFile->Read(&dataLen, SECURE_IO_LOF_SIZE);  // read LoF
156                         if (readItems < SECURE_IO_LOF_SIZE)
157                         {
158                                 if (_SecureIoUtil::IsEndOfFile(pNormalFile.get()) && readItems == 0)
159                                 {
160                                         r = E_END_OF_FILE;
161                                 }
162                                 else
163                                 {
164                                         r = __ConvertNativeErrorToResult(errno);
165                                 }
166
167                                 SysLog(NID_IO, "[%s] Failed to fread file (%ls) in openMode (%s), (errno: %d).",
168                                            GetErrorMessage(r), filePath.GetPointer(), pOpenMode, errno);
169                                 return r;
170                         }
171
172                         if (dataLen > SECURE_FILE_HEADER_SIZE_V1)
173                         {
174                                 r = pNormalFile->Truncate(dataLen);
175                                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to truncate file (%ls) in openMode (%ls).", GetErrorMessage(r));
176
177                                 r = pNormalFile->Flush();
178                                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to flush data to file", GetErrorMessage(r));
179
180                                 r = _SecureIoUtil::SetFlag(pNormalFile.get(), FLAG_STATE_CVF);
181                                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to set flags in file header.", GetErrorMessage(r));
182                         }
183                         else
184                         {
185                                 r = pNormalFile->Truncate(0);
186                                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to truncate file (%ls) in openMode (%s).",
187                                                          GetErrorMessage(r), filePath.GetPointer(), pOpenMode);
188
189                                 r = pNormalFile->Flush();
190                                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to flush data to file", GetErrorMessage(r));
191
192                         }
193                 }
194         }
195
196         __filePath = filePath;
197         __pNormalFile = pNormalFile.release();
198         __pKey = pKey.release();
199
200         return E_SUCCESS;
201 }
202
203 result
204 _SecureFile::Read(ByteBuffer& buffer)
205 {
206         result r = E_SUCCESS;
207         int dataPos = 0;
208         int length = buffer.GetRemaining();
209         int curPos = buffer.GetPosition();
210         int readBytes = 0;
211         const byte* pTempBuffer = null;
212
213         ClearLastResult();
214         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
215
216         SysTryReturnResult(NID_IO, length > 0, E_INVALID_ARG, "Invalid argument passed.");
217         SysAssert(curPos >= 0);
218
219         r = _SecureIoUtil::SelectCipherBlock(__pNormalFile, __virtualFilePointer, &dataPos);
220         if (IsFailed(r))
221         {
222                 if (r == E_STORAGE_FULL)
223                 {
224                         r = E_IO;
225                 }
226                 return r;
227         }
228         pTempBuffer = buffer.GetPointer();
229         r = _SecureIoUtil::ReadDataFromCipherBlock(__pNormalFile, dataPos, length, (const_cast< byte* >(pTempBuffer) + curPos), DATA_FORMAT_BYTE, &readBytes, *__pKey);
230         if (IsFailed(r))
231         {
232                 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File is not opened for reading!");
233                 SysLog(NID_IO, "[%s] Failed to read data from file", GetErrorMessage(r));
234                 return r;
235         }
236
237         SysTryReturnResult(NID_IO, readBytes >= 0, E_IO, "Read bytes value is invalid");
238
239         r = buffer.SetPosition(curPos + readBytes);
240         SysAssert(!IsFailed(r));
241         __virtualFilePointer = __virtualFilePointer + readBytes;
242
243         return r;
244 }
245
246 int
247 _SecureFile::Read(void* pBuffer, int length)
248 {
249         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
250         SysTryReturn(NID_IO, !(pBuffer == null || length <= 0), 0, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument passed.");
251
252         int readBytes = 0;
253         int dataPos = 0;
254         result r = E_SUCCESS;
255
256         r = _SecureIoUtil::SelectCipherBlock(__pNormalFile, __virtualFilePointer, &dataPos);
257         if (IsFailed(r))
258         {
259                 if (r == E_STORAGE_FULL)
260                 {
261                         r = E_IO; //for security error
262                 }
263                 SysPropagate(NID_IO, r);
264                 return 0;
265         }
266
267         r = _SecureIoUtil::ReadDataFromCipherBlock(__pNormalFile, dataPos, length, reinterpret_cast< byte* >(pBuffer), DATA_FORMAT_BYTE, &readBytes, *__pKey);
268         if (IsFailed(r))
269         {
270                 SysTryReturn(NID_IO, !(r == E_INVALID_OPERATION), 0, E_ILLEGAL_ACCESS, "[E_ILLEGAL_ACCESS]File is not opended for reading!");
271                 SysLog(NID_IO, "[%s] Failed to read data from file", GetErrorMessage(r));
272                 SysPropagate(NID_IO, r);
273                 return 0;
274         }
275
276         SysTryReturn(NID_IO, readBytes >= 0, 0, E_IO, "[E_IO] Failed to read specified bytes from file.");
277
278         __virtualFilePointer = __virtualFilePointer + readBytes;
279
280         SetLastResult(r);
281         return readBytes;
282 }
283
284 result
285 _SecureFile::Read(String& buffer)
286 {
287         result r = E_SUCCESS;
288         int dataPos = 0;
289         int readItems = 0;
290         char bstrBuf[FIO_LEN_4K] = {0, };
291
292         ClearLastResult();
293         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
294
295         buffer.Clear();
296
297         r = _SecureIoUtil::SelectCipherBlock(__pNormalFile, __virtualFilePointer, &dataPos);
298         if (IsFailed(r))
299         {
300                 if (r == E_STORAGE_FULL)
301                 {
302                         r = E_IO; //for security error
303                 }
304                 return r;
305         }
306
307         r = _SecureIoUtil::ReadDataFromCipherBlock(__pNormalFile, dataPos, sizeof(bstrBuf), reinterpret_cast< byte* >(bstrBuf), DATA_FORMAT_STRING, &readItems, *__pKey);
308         if (IsFailed(r))
309         {
310                 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File is not opened for reading!");
311                 SysLog(NID_IO, "[%s] Failed to read data from file", GetErrorMessage(r));
312                 return r;
313         }
314         SysAssert(readItems > 0);
315         __virtualFilePointer = __virtualFilePointer + readItems;
316
317         {
318                 String tmp(bstrBuf);
319                 buffer = tmp;
320         }
321
322         return r;
323 }
324
325 result
326 _SecureFile::Write(const ByteBuffer& buffer)
327 {
328         return Write(buffer.GetPointer(), buffer.GetLimit());
329 }
330
331 result
332 _SecureFile::Write(const void* pBuffer, int length)
333 {
334         result r = E_SUCCESS;
335         int dataPos = 0;
336         bool eofSet = false;
337         bool replica = false;
338
339         ClearLastResult();
340         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
341
342         SysTryReturnResult(NID_IO, !(!pBuffer || length <= 0), E_INVALID_ARG, "Invalid argument passed.");
343
344         r = _SecureIoUtil::InsertSecureFileHeader(__pNormalFile);
345         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write file headers.", GetErrorMessage(r));
346
347         r = _SecureIoUtil::SaveLengthOfFile(__pNormalFile);
348         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to set length in file header.", GetErrorMessage(r));
349
350         r = _SecureIoUtil::SelectCipherBlock(__pNormalFile, __virtualFilePointer, &dataPos);
351         if (IsFailed(r))
352         {
353                 if (r == E_END_OF_FILE)
354                 {
355                         r = E_IO; //for security error
356                 }
357                 goto CATCH;
358         }
359
360         if (dataPos == 0)
361         {
362                 eofSet = _SecureIoUtil::IsEndOfFile(__pNormalFile);
363
364                 if (eofSet)
365                 {
366                         r = _SecureIoUtil::SetFlag(__pNormalFile, FLAG_STATE_NONE);
367                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to set flags in file header.", GetErrorMessage(r));
368
369                         replica = false;
370                 }
371                 else
372                 {
373                         r = _SecureIoUtil::MakeCipherBlockReplica(__pNormalFile, __filePath, dataPos, length);
374                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to make cipher block replica of file.", GetErrorMessage(r));
375
376                         r = _SecureIoUtil::SetFlag(__pNormalFile, FLAG_STATE_CTF);
377                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to set flags in file header.", GetErrorMessage(r));
378
379                         replica = true;
380                 }
381
382         }
383         else
384         {
385                 r = _SecureIoUtil::MakeCipherBlockReplica(__pNormalFile, __filePath, dataPos, length);
386                 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to make cipher block replica of file.", GetErrorMessage(r));
387
388                 r = _SecureIoUtil::SetFlag(__pNormalFile, FLAG_STATE_CTF);
389                 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to set flags in file header.", GetErrorMessage(r));
390
391                 replica = true;
392         }
393
394         r = _SecureIoUtil::WriteDataInCipherBlock(__pNormalFile, dataPos, eofSet, length, const_cast< byte* >(static_cast< const byte* >(pBuffer)), *__pKey);
395         if (IsFailed(r))
396         {
397                 if (r == E_END_OF_FILE)
398                 {
399                         r = E_IO; //for security error
400                 }
401                 goto CATCH;
402         }
403
404         if (replica)
405         {
406                 r = _SecureIoUtil::SetFlag(__pNormalFile, FLAG_STATE_CVF_CTF);
407                 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to set flags in file header.", GetErrorMessage(r));
408                 r = _SecureIoUtil::DeleteBlockReplica(__pNormalFile, __filePath);
409                 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failedt to delete block replica of file.", GetErrorMessage(r));
410         }
411
412         r = _SecureIoUtil::SetFlag(__pNormalFile, FLAG_STATE_CVF);
413         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to set flags in file header.", GetErrorMessage(r));
414
415         __virtualFilePointer = __virtualFilePointer + length;
416
417 CATCH:
418
419         SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File is not opened for writing!");
420
421         return r;
422 }
423
424 result
425 _SecureFile::Write(const String& buffer)
426 {
427         unique_ptr< char[] > pData(_StringConverter::CopyToCharArrayN(buffer));
428
429         SysTryReturn(NID_IO, pData != null, GetLastResult(), GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
430
431         return Write(pData.get(), buffer.GetLength());
432 }
433
434 result
435 _SecureFile::Flush(void)
436 {
437         result r = E_SUCCESS;
438         ClearLastResult();
439
440         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
441         r = __pNormalFile->Flush();
442         return r;
443 }
444
445 int
446 _SecureFile::Tell(void) const
447 {
448         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
449
450         long dataLen = 0;
451         result r = E_SUCCESS;
452         int ret = 0;
453
454         r = _SecureIoUtil::GetDataLengh(__pNormalFile, &dataLen);
455         if (IsFailed(r))
456         {
457                 if (r == E_ILLEGAL_ACCESS || r == E_STORAGE_FULL || r == E_END_OF_FILE)
458                 {
459                         r = E_IO; //for security error
460                 }
461                 goto CATCH;
462         }
463
464         SysTryCatch(NID_IO, (dataLen >= __virtualFilePointer), r = E_IO, E_IO, "[E_IO] Failed to tell in file.");
465
466         ret = __virtualFilePointer;
467
468         // fall through
469 CATCH:
470         return ret;
471 }
472
473 result
474 _SecureFile::Seek(FileSeekPosition position, long offset)
475 {
476         result r = E_SUCCESS;
477         long fileEndPos = 0;
478         long tempFilePointer = 0;
479
480         ClearLastResult();
481         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
482
483         r = _SecureIoUtil::GetDataLengh(__pNormalFile, &fileEndPos);
484         if (IsFailed(r))
485         {
486                 if (r == E_ILLEGAL_ACCESS || r == E_END_OF_FILE)
487                 {
488                         r = E_IO; //for security error
489                 }
490                 return r;
491         }
492
493         switch (position)
494         {
495         case FILESEEKPOSITION_BEGIN:
496                 tempFilePointer = 0;
497                 break;
498
499         case FILESEEKPOSITION_CURRENT:
500                 tempFilePointer = __virtualFilePointer;
501                 break;
502
503         case FILESEEKPOSITION_END:
504                 tempFilePointer = fileEndPos;
505                 break;
506
507         default:
508                 SysAssert(false);
509                 break;
510         }
511
512         if (tempFilePointer + offset > fileEndPos)
513         {
514                 //In  Linux , Seek () will set  file position beyond end of file also even if file is opened in READONLY.
515                 if (_write == false)
516                 {
517                         return E_ILLEGAL_ACCESS;
518                 }
519                 else
520                 {
521                         unique_ptr< byte[] > pTempBuffer(new (std::nothrow) byte[tempFilePointer + offset - fileEndPos]);
522                         SysTryReturnResult(NID_IO, pTempBuffer != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
523
524                         memset(pTempBuffer.get(), 0, tempFilePointer + offset - fileEndPos);
525                         __virtualFilePointer = fileEndPos;
526
527                         r = this->Write(pTempBuffer.get(), tempFilePointer + offset - fileEndPos);
528
529                         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write data in to the file.", GetErrorMessage(r));
530
531                 }
532         }
533         else if (tempFilePointer + offset == fileEndPos)
534         {
535                 __virtualFilePointer = fileEndPos;
536         }
537         else if (tempFilePointer + offset < 0)
538         {
539                 return E_INVALID_ARG;
540         }
541         else if (tempFilePointer + offset == 0)
542         {
543                 __virtualFilePointer = 0;
544         }
545         else
546         {
547                 __virtualFilePointer = tempFilePointer + offset;
548         }
549
550         return r;
551 }
552
553 result
554 _SecureFile::Truncate(int length)
555 {
556         result r = E_SUCCESS;
557         long fileEndPos = 0;
558         int readItems = 0;
559         int dataPos = 0;
560
561         ClearLastResult();
562         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
563         SysTryReturnResult(NID_IO, length >= 0, E_INVALID_ARG, "Invalid argument is passed (length < 0)");
564
565         if (length == 0)
566         {
567                 r = __pNormalFile->Truncate(length);
568                 if (r != E_SUCCESS)
569                 {
570                         SysLog(NID_IO, "[%s] Failed to truncate data to file", GetErrorMessage(r));
571                 }
572                 __virtualFilePointer = 0;
573
574                 goto CATCH;
575         }
576
577         r = _SecureIoUtil::GetDataLengh(__pNormalFile, &fileEndPos);
578         if (IsFailed(r))
579         {
580                 if (r == E_END_OF_FILE)
581                 {
582                         r = E_IO; //for security error
583                 }
584                 goto CATCH;
585         }
586
587         if (length >= fileEndPos)
588         {
589                 if (length == fileEndPos)
590                 {
591                         this->Seek(FILESEEKPOSITION_END, 0);
592                         goto CATCH;
593                 }
594                 else
595                 {
596                         unique_ptr< byte[] > pTempBuffer(new (std::nothrow) byte[length - fileEndPos]);
597                         SysTryCatch(NID_IO, pTempBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
598
599
600                         memset(pTempBuffer.get(), 0, length - fileEndPos);
601                         r = this->Seek(FILESEEKPOSITION_END, 0);
602                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to seek in file.", GetErrorMessage(r));
603
604                         r = this->Write(pTempBuffer.get(), length - fileEndPos);
605                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to write data in file.", GetErrorMessage(r));
606                 }
607         }
608         else
609         {
610                 unique_ptr< byte[] > pTempBuffer(null);
611
612                 __virtualFilePointer = length;
613                 r = _SecureIoUtil::SelectCipherBlock(__pNormalFile, __virtualFilePointer, &dataPos);
614                 if (IsFailed(r))
615                 {
616                         if (r == E_END_OF_FILE)
617                         {
618                                 r = E_IO; //for security error
619                         }
620                         goto CATCH;
621                 }
622
623                 if (dataPos != 0)
624                 {
625                         pTempBuffer = unique_ptr< byte[] >(new (std::nothrow) byte[dataPos]);
626                         SysTryCatch(NID_IO, pTempBuffer, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
627
628                         r = _SecureIoUtil::ReadDataFromCipherBlock(__pNormalFile, 0, dataPos, pTempBuffer.get(), DATA_FORMAT_BYTE, &readItems, *__pKey);
629                         if (IsFailed(r))
630                         {
631                                 if (r == E_END_OF_FILE)
632                                 {
633                                         r = E_IO; //for security error
634                                 }
635                                 goto CATCH;
636                         }
637
638                         SysAssert(readItems == dataPos);
639                         r = _SecureIoUtil::SelectCipherBlock(__pNormalFile, __virtualFilePointer, &dataPos);
640                         if (IsFailed(r))
641                         {
642                                 if (r == E_END_OF_FILE)
643                                 {
644                                         r = E_IO; //for security error
645                                 }
646                                 goto CATCH;
647                         }
648                 }
649
650                 length = __pNormalFile->Tell();
651                 SysTryCatch(NID_IO, length != -1, r = __ConvertNativeErrorToResult(errno), r, "[%s] Failed to tell in file", GetErrorMessage(r));
652
653                 r = __pNormalFile->Truncate(length);
654                 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to truncate data to file", GetErrorMessage(r));
655
656
657                 r = __pNormalFile->Flush();
658                 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to flush data to file", GetErrorMessage(r));
659
660
661                 r = _SecureIoUtil::GetDataLengh(__pNormalFile, &__virtualFilePointer);
662                 if (IsFailed(r))
663                 {
664                         if (r == E_END_OF_FILE)
665                         {
666                                 r = E_IO; //for security error
667                         }
668                         goto CATCH;
669                 }
670
671                 if (pTempBuffer != null)
672                 {
673                         r = this->Write(static_cast< void* >(pTempBuffer.get()), dataPos);
674                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to write data in file.", GetErrorMessage(r));
675                 }
676         }
677         r = _SecureIoUtil::GetDataLengh(__pNormalFile, &__virtualFilePointer);
678         if (IsFailed(r))
679         {
680                 if (r == E_END_OF_FILE)
681                 {
682                         r = E_IO; //for security error
683                 }
684                 goto CATCH;
685         }
686
687 CATCH:
688
689         __pNormalFile->Flush();
690         return r;
691 }
692
693 String
694 _SecureFile::GetName(void)
695 {
696         SysAssertf(__pNormalFile != null, "Not yet constructed. Construct() should be called before use.\n");
697
698         SetLastResult(E_SUCCESS); // for OSP 2.0 compatibility
699         return __filePath;
700 }
701
702 }} // Tizen::Io