2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FIo_FileUtil.cpp
20 * @brief This is the implementation file for _FileUtil class.
27 #include <sys/types.h>
34 #include <unique_ptr.h>
37 #include <FIoDirectory.h>
38 #include <FBaseResult.h>
39 #include <FBaseSysLog.h>
41 #include <FBase_StringConverter.h>
42 #include <FBase_NativeError.h>
43 #include <FApp_AppInfo.h>
44 #include <FIo_FileAttributesImpl.h>
45 #include <FIo_SecureIoUtil.h>
46 #include <FIo_FileImpl.h>
47 #include <FIo_FileUtil.h>
50 using namespace Tizen::Base;
51 using namespace Tizen::App;
53 namespace Tizen { namespace Io
56 static const int _BASE_YEAR = 1900;
57 static const int _MAX_COPY_BYTES = 4096;
58 static const int _MAX_OPENMODE_LENGTH = 3;
60 //Holds app path prefixes
61 static const char* filePathAppPrefix[] =
75 "/Storagecard/DownloadedAppPackages",
83 //Holds Media path prefixes
84 static const char* filePathMediaPrefix[] =
90 //Holds system path prefixes
91 static const char* filePathSystemPrefix[] =
93 "/system/configuration",
98 _FileUtil::Remove(const String& filePath)
100 result r = E_SUCCESS;
101 unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
102 SysTryReturn(NID_IO, (pFilePath != null), GetLastResult(), GetLastResult(), ("[%s] Invalid file path."),
103 GetErrorMessage(GetLastResult()));
105 if (_FileUtil::IsFileExist(pFilePath.get()) == false)
107 SysLog(NID_IO, "[E_FILE_NOT_FOUND] File(%s) does not exist.", pFilePath.get());
108 return E_FILE_NOT_FOUND;
111 char resolvedPath[PATH_MAX] = {0,};
112 if (realpath(pFilePath.get(), resolvedPath) == null)
117 r = E_ILLEGAL_ACCESS;
132 r = E_FILE_NOT_FOUND;
139 SysLog(NID_IO, "[%s] Failed to produce canonical absolute path (%ls). errno: %d (%s)",
140 GetErrorMessage(r), filePath.GetPointer(), errno, strerror(errno));
145 int ret = unlink(resolvedPath);
154 r = __ConvertNativeErrorToResult(errno);
155 SysLog(NID_IO, "[%s] Failed to unlink(), errno: %d (%s)", GetErrorMessage(r), errno, strerror(errno));
163 _FileUtil::Move(const String& oldFilePath, const String& newFilePath)
165 result r = E_SUCCESS;
168 unique_ptr<char[]> pOldPath(_StringConverter::CopyToCharArrayN(oldFilePath));
169 SysTryReturn(NID_IO, pOldPath != null, GetLastResult(), GetLastResult(),
170 "[%s] Invalid old file path.", GetErrorMessage(GetLastResult()));
172 unique_ptr<char[]> pNewPath(_StringConverter::CopyToCharArrayN(newFilePath));
173 SysTryReturn(NID_IO, pNewPath != null, GetLastResult(), GetLastResult(),
174 "[%s] Invalid new file path.", GetErrorMessage(GetLastResult()));
176 SysTryReturnResult(NID_IO, _FileUtil::IsFileExist(newFilePath) == false, E_FILE_ALREADY_EXIST,
177 "New file already exists.");
179 SysTryReturnResult(NID_IO, _FileUtil::IsFileExist(oldFilePath) == true, E_FILE_NOT_FOUND,
180 "Old filepath not found.");
182 if (stat(pOldPath.get(), &statBuf) < 0)
184 r = __ConvertNativeErrorToResult(errno);
185 SysLogException(NID_IO, r, "[%s] stat() failed, path: %s, errno: %d (%s)", GetErrorMessage(r), pOldPath.get(), errno, strerror(errno));
188 SysTryReturnResult(NID_IO, S_ISDIR(statBuf.st_mode) == false, E_INVALID_ARG,
189 "The old path is a directory.");
191 // TODO: Use rename() for move operation in same mount point
192 // and need API versioning.
194 int ret = rename(pOldPath.get(), pNewPath.get());
197 r = __ConvertNativeErrorToResult(errno);
198 SysLog(NID_IO, "[%s] rename() failed, errno: %d, strerror: %s", errno, strerror(errno));
202 // To work across different mount points
203 r = File::Copy(oldFilePath, newFilePath, true);
204 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
206 r = File::Remove(oldFilePath);
207 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
214 _FileUtil::Copy(const String& srcFilePath, const String& destFilePath, bool failIfExist)
216 result r = E_SUCCESS;
220 void* pSrcMap = MAP_FAILED;
221 void* pDstMap = MAP_FAILED;
222 unique_ptr<char[]> pBuffer(null);
224 unique_ptr<char[]> pSrcpath(_StringConverter::CopyToCharArrayN(srcFilePath));
225 SysTryReturn(NID_IO, pSrcpath != null, GetLastResult(), GetLastResult(),
226 "[%s] Invalid source file path.", GetErrorMessage(GetLastResult()));
228 unique_ptr<char[]> pDstpath(_StringConverter::CopyToCharArrayN(destFilePath));
229 SysTryReturn(NID_IO, pDstpath != null, GetLastResult(), GetLastResult(),
230 "[%s] Invalid destination file path.", GetErrorMessage(GetLastResult()));
232 SysTryReturnResult(NID_IO, _FileUtil::IsFileExist(srcFilePath) == true, E_FILE_NOT_FOUND,
233 "Source file(%s) does not exist.", pSrcpath.get());
235 if ((_FileUtil::IsFileExist(destFilePath) == true) && (failIfExist == true))
237 r = E_FILE_ALREADY_EXIST;
238 SysLog(NID_IO, "[E_FILE_ALREADY_EXIST] Destination file already exists.");
242 // try linux way to optimally use mmap.
243 srcFd = open(pSrcpath.get(), O_RDONLY);
244 r = __ConvertNativeErrorToResult(errno);
245 SysTryReturn(NID_IO, (srcFd != -1), r, r, "[%s] Failed to open file (%s).", __ConvertNativeErrorToMessage(errno), pSrcpath.get());
247 dstFd = open(pDstpath.get(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
248 r = __ConvertNativeErrorToResult(errno);
249 SysTryCatch(NID_IO, (dstFd != -1), , r, "[%s] Failed to open file (%s), errno: %d (%s)",
250 __ConvertNativeErrorToMessage(errno), pDstpath.get(), errno, strerror(errno));
252 // First try the mmap method
253 size = lseek(srcFd, 0, SEEK_END);
254 r = __ConvertNativeErrorToResult(errno);
255 SysTryCatch(NID_IO, (size != -1), , r, "[%s] Failed to reach the end of file (%s).", __ConvertNativeErrorToMessage(
256 errno), pDstpath.get());
258 pSrcMap = mmap(0, size, PROT_READ, MAP_SHARED, srcFd, 0);
259 pDstMap = mmap(0, size, PROT_WRITE, MAP_SHARED, dstFd, 0);
261 if ((pSrcMap != MAP_FAILED) && (pDstMap != MAP_FAILED))
263 // do the copy and commit
264 memcpy(pDstMap, pSrcMap, size);
265 msync(pDstMap, size, MS_SYNC);
267 else // mmap method filed due to memory limitations.. try regular copy
269 off_t start = lseek(srcFd, 0, SEEK_SET);
270 r = __ConvertNativeErrorToResult(errno);
271 SysTryCatch(NID_IO, (start != -1), , r, "[%s] Failed to reach the end of file (%s).", __ConvertNativeErrorToMessage(
272 errno), pDstpath.get());
274 pBuffer = unique_ptr<char[]> (new (std::nothrow) char[_MAX_COPY_BYTES]);
275 SysTryCatch(NID_IO, (pBuffer != null), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
277 ssize_t bytesRead = -1;
278 ssize_t bytesWritten = -1;
281 bytesRead = read(srcFd, pBuffer.get(), _MAX_COPY_BYTES);
282 r = __ConvertNativeErrorToResult(errno);
283 SysTryCatch(NID_IO, bytesRead != -1, , r, "[%s] Failed to read from file (%s), errno: %d",
284 __ConvertNativeErrorToMessage(errno), pSrcpath.get(), errno);
286 bytesWritten = write(dstFd, pBuffer.get(), bytesRead);
287 r = __ConvertNativeErrorToResult(errno);
288 SysTryCatch(NID_IO, bytesWritten != -1, , r, "[%s] Failed to write to file (%s), errno: %d",
289 __ConvertNativeErrorToMessage(
290 errno), pDstpath.get(), errno);
311 if (pSrcMap != MAP_FAILED && size != -1)
313 munmap(pSrcMap, size);
316 if (pDstMap != MAP_FAILED && size != -1)
318 munmap(pDstMap, size);
325 _FileUtil::GetAttributes(const String& filePath, FileAttributes& attribute)
328 DateTime modifiedTime;
329 long long fileSize = 0;
330 unsigned long attr = 0;
331 result r = E_SUCCESS;
332 struct tm* pTm = null;
333 String fileName = L"";
336 unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
337 SysTryReturn(NID_IO, (pFilePath != null), GetLastResult(), GetLastResult(), "[%s] Invalid source file path.",
338 GetErrorMessage(GetLastResult()));
341 if (int ret = stat(pFilePath.get(), &statbuf) == -1)
343 r = __ConvertNativeErrorToResult(errno);
344 SysLogException(NID_IO, r, "[%s] Failed to get file (%s) status.", GetErrorMessage(r), pFilePath.get());
349 fileSize = statbuf.st_size;
352 attr = statbuf.st_mode;
354 // time of last status change
355 pTm = localtime(&statbuf.st_ctime);
356 SysTryReturnResult(NID_IO, pTm != null, E_SYSTEM, "Failed to call localtime() (%s).", strerror(errno));
357 r = dateTime.SetValue(_BASE_YEAR + pTm->tm_year, 1 + pTm->tm_mon, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec);
358 SysTryReturn(NID_IO, (!IsFailed(r)), r, r, "[%s] Failed to set DateTime.", GetErrorMessage(r));
360 // time of last modification
361 pTm = localtime(&statbuf.st_mtime);
362 SysTryReturnResult(NID_IO, pTm != null, E_SYSTEM, "Failed to call localtime() (%s).", strerror(errno));
363 r = modifiedTime.SetValue(_BASE_YEAR + pTm->tm_year, 1 + pTm->tm_mon, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec);
364 SysTryReturn(NID_IO, (!IsFailed(r)), r, r, "[%s] Failed to set DateTime.", GetErrorMessage(r));
366 fileName = _FileUtil::GetFileName(filePath);
367 if (fileName.StartsWith(L".", 0)) // including . and ..
372 _FileAttributesImpl::GetInstance(attribute)->Set(dateTime, modifiedTime, fileSize, attr, hidden);
378 _FileUtil::GetFileName(const String& filePath)
383 result r = filePath.LastIndexOf(L'/', filePath.GetLength() - 1, pos);
384 SysTryReturn(NID_IO, !IsFailed(r), fileName, E_INVALID_ARG, "[E_INVALID_ARG] The file path is invalid.");
386 r = filePath.SubString(pos + 1, fileName);
387 SysTryReturn(NID_IO, !IsFailed(r), fileName, E_INVALID_ARG, "[E_INVALID_ARG] The file path is invalid.");
388 SysTryReturn(NID_IO, fileName.GetLength() > 0 && fileName.GetLength() <= NAME_MAX, fileName, E_INVALID_ARG,
389 "[E_INVALID_ARG] The length of file name is zero or exceeds system limitations.");
391 SetLastResult(E_SUCCESS);
396 _FileUtil::GetFileExtension(const String& filePath)
401 result r = filePath.LastIndexOf(L'/', filePath.GetLength() - 1, pos);
402 SysTryReturn(NID_IO, !IsFailed(r), extName, E_INVALID_ARG, "[E_INVALID_ARG] The file path is invalid.");
405 r = filePath.SubString(pos + 1, fileName);
406 SysTryReturn(NID_IO, !IsFailed(r), extName, E_INVALID_ARG, "[E_INVALID_ARG] The file path is invalid.");
407 SysTryReturn(NID_IO, fileName.GetLength() > 0 && fileName.GetLength() <= NAME_MAX, extName, E_INVALID_ARG,
408 "[E_INVALID_ARG] The length of file name is zero or exceeds system limitations.");
410 r = fileName.LastIndexOf(L'.', fileName.GetLength() - 1, pos);
411 SysTryReturn(NID_IO, !IsFailed(r), extName, E_INVALID_ARG, "[E_INVALID_ARG] The file path is invalid.");
413 r = fileName.SubString(pos + 1, extName);
414 SysTryReturn(NID_IO, !IsFailed(r), extName, E_INVALID_ARG, "[E_INVALID_ARG] The file path is invalid.");
416 SetLastResult(E_SUCCESS);
421 _FileUtil::IsFileExist(const String& filePath)
424 result r = E_SUCCESS;
426 unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
427 SysTryReturn(NID_IO, (pFilePath != null), false, GetLastResult(), ("[%s] Invalid file path."),
428 GetErrorMessage(GetLastResult()));
430 ret = access(pFilePath.get(), F_OK);
442 r = __ConvertNativeErrorToResult(errno);
448 return (ret == 0) ? true : false;
453 _FileUtil::IsEncrypted(const String& filePath)
455 result r = E_SUCCESS;
456 // TODO: int pathKind;
459 bool encrypted = false;
460 // TODO: bool checkPrivilege = false;
461 byte secureHeader[SECURE_FILE_HEADER_SIZE_V1 + SECURE_IO_LOF_SIZE];
462 byte reservedValue[SECURE_IO_STATIC_BIN_LEN] = {0xCA, 0xFE, 0xBE, 0xBE, 0xDA, 0xEF, 0xEB, 0xEB};
463 char magicNum1[SECURE_IO_MAGIC_NUMBER_SIZE] = {0xCA, 0xFE, 0xBE, 0xBE};
464 char magicNum2[SECURE_IO_MAGIC_NUMBER_SIZE] = {0xDA, 0xEF, 0xEF, 0xEB};
467 unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
468 SysTryReturn(NID_IO, pFilePath != null, false, E_INVALID_ARG, "[E_INVALID_ARG] CopyToCharArrayN failed!");
470 fileLength = strlen(pFilePath.get());
471 SysTryReturn(NID_IO, fileLength > 0, false, E_INVALID_ARG, "[E_INVALID_ARG] CopyToCharArrayN failed!");
473 if (pFilePath[fileLength - 1] == ('/'))
475 pFilePath[fileLength - 1] = ('\0'); // remove last '/' character if exists.
478 // // TODO: check accessibility to path
479 // r = CheckAccessibilityToPath(pFilePath, &pathKind, 0);
483 // if(pathKind == __PATH_KIND_AUTHORIZED_MMC)
485 // __CheckPrivilege(PRV_INSTALLATION, checkPrivilege);
486 // if(!checkPrivilege)
488 // r = E_ILLEGAL_ACCESS;
492 // else if(pathKind == __PATH_KIND_AUTHORIZED_LINK || pathKind == __PATH_KIND_AUTHORIZED_NPKI ||
493 // pathKind == __PATH_KIND_AUTHORIZED_PRELOADED_MEDIA)
495 // __CheckPrivilege(PRV_PRIVILEGED_IO, checkPrivilege);
496 // if(!checkPrivilege)
498 // r = E_ILLEGAL_ACCESS;
502 // else if (pathKind == __PATH_KIND_APP_DENY)
504 // r = E_ILLEGAL_ACCESS;
508 pFile = fopen(pFilePath.get(), "r");
511 r = __ConvertNativeErrorToResult(errno);
512 SysLog(NID_IO, "[%s] Failed to open file (%s) in openMode (%s), (errno: %d).", GetErrorMessage(r), pFilePath.get(), "r", errno);
516 readItems = fread(secureHeader, 1, SECURE_FILE_HEADER_SIZE_V1 + SECURE_IO_LOF_SIZE, pFile);
518 if (readItems < (SECURE_FILE_HEADER_SIZE_V1 + SECURE_IO_LOF_SIZE))
520 int eof = feof((FILE*)pFile);
528 r = __ConvertNativeErrorToResult(errno);
529 SysLog(NID_IO, "[%s] Failed to open file (%s) in openMode (%s), (errno: %d).", GetErrorMessage(r), pFilePath.get(), "r", errno);
533 if (memcmp(secureHeader, SECURE_FILE_HEADER_STRING, SECURE_FILE_HEADER_STRING_SIZE) == 0 && \
534 memcmp(secureHeader + SECURE_FILE_HEADER_STRING_SIZE, reservedValue, SECURE_IO_STATIC_BIN_LEN) == 0)
538 else if (memcmp(secureHeader, SECURE_REG_HEADER_STRING, SECURE_REG_HEADER_STRING_SIZE) == 0 && \
539 memcmp(secureHeader + SECURE_REG_HEADER_STRING_SIZE, reservedValue, SECURE_IO_STATIC_BIN_LEN) == 0)
543 else if ((memcmp(secureHeader, magicNum1, SECURE_IO_MAGIC_NUMBER_SIZE) == 0) &&
544 (memcmp(secureHeader + SECURE_IO_STATIC_BIN_LEN, magicNum2, SECURE_IO_MAGIC_NUMBER_SIZE) == 0))
568 _FileUtil::IsAppPath(const String& filePath)
570 result r = E_SUCCESS;
572 if (VerifyFilePath(filePath, FILEPATH_TYPE_APP))
574 SetLastResult(E_SUCCESS);
584 _FileUtil::IsMediaPath(const String& filePath)
586 result r = E_SUCCESS;
588 if (VerifyFilePath(filePath, FILEPATH_TYPE_MEDIA))
590 SetLastResult(E_SUCCESS);
600 _FileUtil::IsSystemPath(const String& filePath)
602 result r = E_SUCCESS;
604 if (VerifyFilePath(filePath, FILEPATH_TYPE_SYSTEM))
606 SetLastResult(E_SUCCESS);
616 _FileUtil::VerifyFilePath(const String& filePath, _FilePathType pathType)
618 result r = E_SUCCESS;
620 String absolutePath("");
624 char** ppPathList = null;
625 bool candidateFound = false;
628 //TODO Apply realpath after data caging.
630 //char resolved_path[1024];
631 //char* pFilePath = _StringConverter::CopyToCharArrayN(filePath);
633 //r = GetLastResult();
635 //SysTryCatch(NID_IO, pFilePath != null,
636 // r, r, "[%s] Failed to get file path", GetErrorMessage(r));
639 //SysLog(NID_IO, "convert: %s", pFilePath);
640 //if (realpath(pFilePath, resolved_path) !=0)
642 // r = __ConvertNativeErrorToResult(errno);
643 // SysLog(NID_IO, "convert Error!!! [%s] %s", resolved_path, GetErrorMessage(r));
644 // delete[] pFilePath;
648 //SysLog(NID_IO, "convert result: %s", resolved_path);
649 //absolutePath.Append(resolved_path);
650 //delete[] pFilePath;
652 absolutePath.Append(filePath);
653 // This code does not handle paths without prefix '/' ex: "Home/myfile"
654 // since it depends on cwd.
657 case FILEPATH_TYPE_APP:
658 pathCount = MAX_FILEPATH_APP;
659 ppPathList = const_cast <char**>(filePathAppPrefix);
662 case FILEPATH_TYPE_MEDIA:
663 pathCount = MAX_FILEPATH_MEDIA;
664 ppPathList = const_cast <char**>(filePathMediaPrefix);
667 case FILEPATH_TYPE_SYSTEM:
668 pathCount = MAX_FILEPATH_SYSTEM;
669 ppPathList = const_cast <char**>(filePathSystemPrefix);
677 absolutePath.GetCharAt(absolutePath.GetLength() - 1, ch);
678 if (ch != L'/') // if last char of absolutePath is not '/' then append it to make path parsing easier
680 absolutePath.Append(L'/');
683 for (i = 0; i < pathCount; i++)
686 tmpStr.Append(ppPathList[i]);
688 if (absolutePath.IndexOf(tmpStr, 0, index) == E_SUCCESS)
693 if (absolutePath.GetCharAt(tmpStr.GetLength(), ch) == E_SUCCESS)
695 if (ch == L'/') // validate exact path. paths like /Home123/file.txt is not supported.
697 candidateFound = true;
705 if (candidateFound == true)
727 _FileUtil::ConvertToSecureFile(const String& plainFilePath, const String& secureFilePath, const ByteBuffer* pKey)
729 SysTryReturnResult(NID_IO, plainFilePath.GetLength() > 0 && plainFilePath.GetLength() <= PATH_MAX, E_INVALID_ARG,
730 "Invalid argument was passed. Given file name length is not correct!");
731 SysTryReturnResult(NID_IO, plainFilePath.EndsWith(L"/") == false, E_INVALID_ARG,
732 "Invalid argument was passed. Given file name is not correct! - ends with '/'");
734 SysTryReturnResult(NID_IO, secureFilePath.GetLength() > 0 && secureFilePath.GetLength() <= PATH_MAX, E_INVALID_ARG,
735 "Invalid argument was passed. Given file name length is not correct!");
736 SysTryReturnResult(NID_IO, secureFilePath.EndsWith(L"/") == false, E_INVALID_ARG,
737 "Invalid argument was passed. Given file name is not correct! - ends with '/'");
741 int lastBlockSize = 0;
745 unique_ptr<byte[]> pBuffer(null);
746 result r = E_SUCCESS;
748 if (File::IsFileExist(secureFilePath))
753 r = E_FILE_ALREADY_EXIST;
754 SysLog(NID_IO, "[E_FILE_ALREADY_EXIST] The secure file already exist.");
758 SysLog(NID_IO, "[%s] Propagated.", GetErrorMessage(r));
763 unique_ptr<File> pFile(new (std::nothrow) File());
764 SysTryReturnResult(NID_IO, pFile != null, E_OUT_OF_MEMORY, "Unable to create Io::File");
766 r = pFile->Construct(plainFilePath, L"r", false);
769 if (r == E_MAX_EXCEEDED)
773 SysLog(NID_IO, "[%s] Propagated.", GetErrorMessage(r));
777 r = pFile->Seek(FILESEEKPOSITION_END, 0);
778 SysTryReturn(NID_IO, r == E_SUCCESS , r, r, "[%s] Propagated", GetErrorMessage(r));
780 fileSize = pFile->Tell();
782 r = pFile->Seek(FILESEEKPOSITION_BEGIN, 0);
783 SysTryReturn(NID_IO, r == E_SUCCESS , r, r, "[%s] Propagated", GetErrorMessage(r));
785 unique_ptr<File> pSecureFile(new (std::nothrow) File());
786 SysTryReturnResult(NID_IO, pSecureFile != null, E_OUT_OF_MEMORY,
787 "Unable to create Io::File");
789 r = pSecureFile->Construct(secureFilePath, "w", *pKey);
790 SysTryReturn(NID_IO, r == E_SUCCESS , r, r, "[%s] Propagated", GetErrorMessage(r));
797 lastBlockSize = fileSize % CIPHER_BLOCK_SIZE;
798 if (lastBlockSize == 0)
800 blockCount = fileSize / CIPHER_BLOCK_SIZE;
801 lastBlockSize = CIPHER_BLOCK_SIZE;
805 blockCount = fileSize / CIPHER_BLOCK_SIZE + 1;
808 for(count = 0; count < blockCount; count++)
812 memset(pBuffer.get(), 0, CIPHER_BLOCK_SIZE);
815 if ((count + 1) == blockCount && pBuffer == null)
817 pBuffer.reset(new (std::nothrow) byte[lastBlockSize]);
818 SysTryReturnResult(NID_IO, pBuffer != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
819 memset(pBuffer.get(), 0, lastBlockSize);
820 bufferSize = lastBlockSize;
823 else if ((count + 1) != blockCount && pBuffer == null)
825 pBuffer.reset(new (std::nothrow) byte[CIPHER_BLOCK_SIZE]);
826 SysTryReturnResult(NID_IO, pBuffer != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
827 memset(pBuffer.get(), 0, CIPHER_BLOCK_SIZE);
828 bufferSize = CIPHER_BLOCK_SIZE;
831 readSize = pFile->Read(pBuffer.get(), bufferSize);
835 if (r == E_END_OF_FILE)
839 SysLog(NID_IO, "[%s] Propagated.", GetErrorMessage(r));
843 r = pSecureFile->Write(pBuffer.get(), readSize);
844 SysTryReturn(NID_IO, r == E_SUCCESS , r, r, "[%s] Propagated", GetErrorMessage(r));