Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_fileSystem.c Source File

pal_plat_fileSystem.c

00001 #include "pal.h"
00002 #include "pal_plat_fileSystem.h"
00003 #include "pal_plat_rtos.h"
00004 
00005 
00006 #if defined(__GNUC__) && !defined(__CC_ARM)
00007 #include <sys/stat.h>
00008 #include <sys/types.h>
00009 #endif // defined(__GNUC__) && !defined(__CC_ARM)
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <stdlib.h>
00013 #include "fsl_mpu.h"
00014 #include "ff.h"
00015 #include "diskio.h"
00016 #include "sdhc_config.h"
00017 
00018 
00019 #define CHK_FD_VALIDITY(x) ((FIL *)x)->fs->id != ((FIL *)x)->id
00020 #define PAL_FS_ALIGNMENT_TO_SIZE    4                                                          //!< This Size control the number of bytes written to the file (bug fix for writing unaligned memory to file)
00021 #define PAL_FS_COPY_BUFFER_SIZE 256                                                            //!< Size of the chunk to copy files
00022 PAL_PRIVATE BYTE g_platOpenModeConvert[] =
00023 {
00024         0,
00025         FA_READ | FA_OPEN_EXISTING,                //"r"
00026         FA_WRITE | FA_READ| FA_OPEN_EXISTING,    //"r+"
00027         FA_WRITE | FA_READ| FA_CREATE_NEW,         //"w+x"
00028         FA_WRITE | FA_READ| FA_CREATE_ALWAYS    //"w+"
00029 };    //!< platform convert table for \b fopen() modes
00030 
00031 
00032 /*! \brief This function find the next file in a directory
00033  *
00034  * @param[in]    *dh - Directory handler to an open DIR
00035  * @param[out]    CurrentEntry - entry for the file found in Directory (pre allocated)
00036  *
00037  * \return true - upon successful operation.\n
00038  *
00039  */
00040 PAL_PRIVATE bool pal_plat_findNextFile(DIR *dh, FILINFO  * CurrentEntry);
00041 
00042 /*! \brief This function translate the platform errors opcode to pal error codes
00043  *
00044  * @param[in]    errorOpCode - platform opcode to be translated
00045  *
00046  * \return PAL_SUCCESS upon successful operation.\n
00047  */
00048 PAL_PRIVATE palStatus_t pal_plat_errorTranslation (int errorOpCode);
00049 
00050 /*! \brief This function build the full path name by adding the filename to the working path given in pathName arg
00051  *
00052  * @param[in]    *pathName - pointer to the null-terminated string that specifies the directory name.
00053  * @param[in]   *fileName - pointer to the file name
00054  * @param[out]    *fullPath - pointer to the full path including the filename (pre allocated)
00055  *
00056  * \return PAL_SUCCESS upon successful operation.\n
00057  *         PAL_FILE_SYSTEM_ERROR - see error code description \c palError_t
00058  *
00059  */
00060 PAL_PRIVATE palStatus_t pal_plat_addFileNameToPath(const char *pathName, const char * fileName, char * fullPath);
00061 
00062 /*! \brief This function copy one file from source folder to destination folder
00063  *
00064  * @param[in]  pathNameSrc - Pointer to a null-terminated string that specifies the source dir.
00065  * @param[in]  pathNameDest - Pointer to a null-terminated string that specifies the destination dir
00066  * @param[in] fileName - pointer the the file name
00067  *
00068  * \return PAL_SUCCESS upon successful operation.\n
00069  *         PAL_FILE_SYSTEM_ERROR - see error code description \c palError_t
00070  *
00071  * \note File should not be open.\n
00072  *         If the Destination file exist then it shall be truncated
00073  *
00074  */
00075 PAL_PRIVATE palStatus_t pal_plat_fsCpFile(const char *pathNameSrc,  char *pathNameDest, char * fileName);
00076 
00077 palStatus_t pal_plat_fsMkdir(const char *pathName)
00078 {
00079     palStatus_t ret = PAL_SUCCESS;
00080     FRESULT status = FR_OK;
00081     status = f_mkdir(pathName);
00082     if (status != FR_OK)
00083     {
00084         ret = pal_plat_errorTranslation(status);
00085     }
00086     return ret;
00087 }
00088 
00089 
00090 palStatus_t pal_plat_fsRmdir(const char *pathName)
00091 {
00092     palStatus_t ret = PAL_SUCCESS;
00093     FRESULT status = FR_OK;
00094 
00095     status = f_unlink(pathName);
00096     if (status != FR_OK)
00097     {
00098         if ( status == FR_DENIED)
00099         {
00100             ret = PAL_ERR_FS_DIR_NOT_EMPTY;
00101         }
00102         else if (status == FR_NO_FILE)
00103         {
00104             ret = PAL_ERR_FS_NO_PATH;
00105         }
00106         else
00107         {
00108             ret = pal_plat_errorTranslation(status);
00109         }
00110     }
00111 
00112     return ret;
00113 }
00114 
00115 
00116 palStatus_t pal_plat_fsFopen(const char *pathName, pal_fsFileMode_t mode, palFileDescriptor_t *fd)
00117 {
00118     palStatus_t ret = PAL_SUCCESS;
00119     FRESULT status = FR_OK;
00120     FIL * descriptor = NULL;
00121 
00122     descriptor = (FIL *)pal_plat_malloc (sizeof(FIL));
00123     if (descriptor)
00124     {
00125         *fd = (palFileDescriptor_t)descriptor;
00126         status = f_open((FIL*)*fd, pathName, g_platOpenModeConvert[mode]);
00127         if (FR_OK != status)
00128         {
00129             pal_plat_free (descriptor);
00130             if(FR_NO_PATH == status)
00131             {
00132                 ret = PAL_ERR_FS_NO_FILE;
00133             }
00134             else
00135             {
00136                 ret = pal_plat_errorTranslation(status);
00137             }
00138         }
00139     }
00140 
00141     return ret;
00142 }
00143 
00144 
00145 palStatus_t pal_plat_fsFclose(palFileDescriptor_t *fd)
00146 {
00147     FRESULT status = FR_OK;
00148     palStatus_t ret = PAL_SUCCESS;
00149 
00150 
00151     if (CHK_FD_VALIDITY(*fd))
00152     {//Bad File Descriptor
00153         ret = PAL_ERR_FS_BAD_FD;
00154         return ret;
00155     }
00156 
00157     status = f_close((FIL *)*fd);
00158     if (FR_OK != status)
00159     {
00160         ret = pal_plat_errorTranslation(status);
00161     }
00162     else
00163     {
00164         pal_plat_free ((void*)*fd);
00165     }
00166     return ret;
00167 }
00168 
00169 
00170 palStatus_t pal_plat_fsFread(palFileDescriptor_t *fd, void * buffer, size_t numOfBytes, size_t *numberOfBytesRead)
00171 {
00172     palStatus_t ret = PAL_SUCCESS;
00173     FRESULT status = FR_OK;
00174     uint8_t readaligment[PAL_FS_ALIGNMENT_TO_SIZE] = { 0 };
00175     uint32_t index = 0;
00176     size_t byteRead = 0;
00177     uint8_t  leftover = 0;
00178 
00179     if (CHK_FD_VALIDITY(*fd))
00180     {//Bad File Descriptor
00181         ret = PAL_ERR_FS_BAD_FD;
00182         return ret;
00183     }
00184 
00185     leftover = numOfBytes % PAL_FS_ALIGNMENT_TO_SIZE;
00186     for(index = 0; index < (numOfBytes / PAL_FS_ALIGNMENT_TO_SIZE); index++)
00187     {
00188         status = f_read((FIL *)*fd, readaligment, PAL_FS_ALIGNMENT_TO_SIZE, &byteRead);
00189         if (FR_OK != status)
00190         {
00191             ret = pal_plat_errorTranslation(status);
00192             break;
00193         }
00194         else
00195         {
00196             memcpy(&((uint8_t *)buffer)[*numberOfBytesRead], readaligment, PAL_FS_ALIGNMENT_TO_SIZE);
00197             *numberOfBytesRead += byteRead;
00198         }
00199     }
00200 
00201     if ((ret == PAL_SUCCESS) && (leftover > 0))
00202     {
00203         status = f_read((FIL *)*fd, readaligment, PAL_FS_ALIGNMENT_TO_SIZE, &byteRead);
00204         if (FR_OK != status)
00205         {
00206             ret = pal_plat_errorTranslation(status);
00207         }
00208         else
00209         {
00210             memcpy(&((uint8_t *)buffer)[*numberOfBytesRead], readaligment, leftover);
00211             *numberOfBytesRead += leftover;
00212             ret = pal_fsFseek(fd, leftover - PAL_FS_ALIGNMENT_TO_SIZE ,PAL_FS_OFFSET_SEEKCUR);
00213         }
00214     }
00215 
00216     return ret;
00217 }
00218 
00219 
00220 palStatus_t pal_plat_fsFwrite(palFileDescriptor_t *fd, const void *buffer, size_t numOfBytes, size_t *numberOfBytesWritten)
00221 {
00222     palStatus_t ret = PAL_SUCCESS;
00223     FRESULT status = FR_OK;
00224     uint32_t index = 0;
00225     size_t bytesWritten = 0;
00226     uint8_t  leftover = 0;
00227 
00228     if (CHK_FD_VALIDITY(*fd))
00229     {//Bad File Descriptor
00230         ret = PAL_ERR_FS_BAD_FD;
00231         return ret;
00232     }
00233 
00234     leftover = numOfBytes % PAL_FS_ALIGNMENT_TO_SIZE;
00235     for (index = 0; index < (numOfBytes / PAL_FS_ALIGNMENT_TO_SIZE); index++)
00236     {
00237         status = f_write((FIL *)*fd, ((uint8_t *)buffer + *numberOfBytesWritten), PAL_FS_ALIGNMENT_TO_SIZE, &bytesWritten);
00238         if (FR_OK != status)
00239         {
00240             ret = pal_plat_errorTranslation(status);
00241             break;
00242         }
00243         else if (PAL_FS_ALIGNMENT_TO_SIZE != bytesWritten)
00244         {
00245             ret = PAL_ERR_FS_INSUFFICIENT_SPACE;
00246         }
00247         else
00248         {
00249             *numberOfBytesWritten += bytesWritten;
00250         }
00251     }
00252 
00253     if ((ret == PAL_SUCCESS) && (leftover > 0))
00254     {
00255         status = f_write((FIL *)*fd, ((uint8_t *)buffer + *numberOfBytesWritten), leftover, &bytesWritten);
00256         if (FR_OK != status)
00257         {
00258             ret = pal_plat_errorTranslation(status);
00259         }
00260         else if (leftover != bytesWritten)
00261         {
00262             ret = PAL_ERR_FS_INSUFFICIENT_SPACE;
00263         }
00264         else
00265         {
00266             *numberOfBytesWritten += bytesWritten;
00267         }
00268     }
00269 
00270     return ret;
00271 }
00272 
00273 
00274 palStatus_t pal_plat_fsFseek(palFileDescriptor_t *fd, int32_t offset, pal_fsOffset_t whence)
00275 {
00276     palStatus_t ret = PAL_SUCCESS;
00277     FRESULT status = FR_OK;
00278     uint32_t  fatFSOffset = 0;
00279 
00280     if (CHK_FD_VALIDITY(*fd))
00281     {//Bad File Descriptor
00282         ret = PAL_ERR_FS_BAD_FD;
00283         return ret;
00284     }
00285 
00286 
00287     switch(whence)
00288     {
00289     case PAL_FS_OFFSET_SEEKCUR:
00290         if (((-1)*offset  > f_tell((FIL*)*fd) && (offset < 0)) || (offset  > f_tell((FIL*)*fd) && (offset > 0)))
00291         {
00292             ret = PAL_ERR_FS_ERROR;
00293         }
00294         else
00295         {
00296             fatFSOffset = f_tell((FIL*)*fd) + offset;
00297         }
00298         break;
00299 
00300     case PAL_FS_OFFSET_SEEKEND:
00301         if ((-1)*offset  > f_size((FIL*)*fd) || (offset > 0))
00302         {
00303             ret = PAL_ERR_FS_ERROR;
00304         }
00305         else
00306         {
00307             fatFSOffset = f_size((FIL*)*fd) + offset;
00308         }
00309         break;
00310 
00311     case PAL_FS_OFFSET_SEEKSET:
00312         if (offset >  f_size((FIL*)*fd))
00313         {
00314             ret = PAL_ERR_FS_ERROR;
00315         }
00316         else
00317         {
00318             fatFSOffset = offset;
00319         }
00320         break;
00321 
00322     default:
00323         fatFSOffset = 0;
00324         break;
00325     }
00326 
00327     if (ret == PAL_SUCCESS)
00328     {
00329         status = f_lseek ((FIL *)*fd, fatFSOffset);
00330         if (FR_OK != status)
00331         {
00332             ret = pal_plat_errorTranslation(status);
00333         }
00334     }
00335     return ret;
00336 }
00337 
00338 
00339 palStatus_t pal_plat_fsFtell(palFileDescriptor_t *fd, int32_t * pos)
00340 {
00341     palStatus_t ret = PAL_SUCCESS;
00342 
00343     if (CHK_FD_VALIDITY(*fd))
00344     {//Bad File Descriptor
00345         ret = PAL_ERR_FS_BAD_FD;
00346     }
00347     else
00348     {
00349         *pos = f_tell((FIL*)*fd);
00350     }
00351     return ret;
00352 }
00353 
00354 
00355 palStatus_t pal_plat_fsUnlink(const char *pathName)
00356 {
00357     palStatus_t ret = PAL_SUCCESS;
00358     FRESULT status = FR_OK;
00359 
00360     status = f_unlink(pathName);
00361     if (status != FR_OK)
00362     {
00363         if (status == FR_DENIED)
00364         {
00365             ret = PAL_ERR_FS_DIR_NOT_EMPTY;
00366         }
00367         else
00368         {
00369             ret = pal_plat_errorTranslation(status);
00370         }
00371     }
00372     return ret;
00373 }
00374 
00375 
00376 palStatus_t pal_plat_fsRmFiles(const char *pathName)
00377 {
00378     DIR dh; //Directory handler
00379     palStatus_t ret = PAL_SUCCESS;
00380     FRESULT status = FR_OK;
00381     char buffer[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; //Buffer for coping the name and folder
00382     FILINFO  currentEntry = { 0 }; //file Entry
00383 
00384     status = f_opendir(&dh, pathName);
00385     if (status != FR_OK)
00386     {
00387         ret = pal_plat_errorTranslation(status);
00388     }
00389 
00390     if (ret == PAL_SUCCESS)
00391     {
00392         while(true)
00393         {
00394             if (!pal_plat_findNextFile(&dh, &currentEntry))
00395             {
00396                 ret = PAL_ERR_FS_ERROR_IN_SEARCHING;
00397                 break;
00398             }
00399             pal_plat_addFileNameToPath(pathName, currentEntry.fname, buffer);
00400             if (currentEntry.fname[0] != '\0')
00401             {
00402                 if (currentEntry.fattrib & AM_DIR)
00403                 {
00404                     ret = pal_fsRmFiles(buffer);
00405                     if (ret != PAL_SUCCESS)
00406                     {
00407                         break;
00408                     }
00409                     ret = pal_fsRmDir(buffer);
00410                     if (PAL_SUCCESS != ret)
00411                     {
00412                         break;
00413                     }
00414                 }
00415                 else
00416                 {
00417                     status = f_unlink (buffer);
00418                     if (status != FR_OK)
00419                     {
00420                         ret = pal_plat_errorTranslation(status);
00421                         break;
00422                     }
00423                 }
00424             }
00425             else
00426             {//End of directory reached  without errors break, close directory and exit
00427                 break;
00428             }
00429         }//while()
00430 
00431         status = f_closedir (&dh); //Close DIR handler
00432         if (status != FR_OK)
00433         {
00434             ret = pal_plat_errorTranslation(status);
00435         }
00436     }
00437 
00438     return ret;
00439 }
00440 
00441 
00442 palStatus_t pal_plat_fsCpFolder(const char *pathNameSrc,  char *pathNameDest)
00443 {
00444     DIR src_dh; //Directory for the source Directory handler
00445     palStatus_t ret = PAL_SUCCESS;
00446     FILINFO currentEntry = { 0 }; //file Entry
00447     FRESULT status = FR_OK;
00448 
00449 
00450     status = f_opendir(&src_dh, pathNameSrc);
00451     if (status != FR_OK)
00452     {
00453         ret = pal_plat_errorTranslation(status);
00454     }
00455 
00456 
00457     if (ret == PAL_SUCCESS)
00458     {
00459         while(true)
00460         {
00461             if (!pal_plat_findNextFile(&src_dh, &currentEntry))
00462             {
00463                 ret = PAL_ERR_FS_ERROR_IN_SEARCHING;
00464                 break;
00465             }
00466             if (currentEntry.fname[0] != 0)
00467             {
00468                 if (currentEntry.fattrib & AM_DIR) // skip all folder as this is flat copy only
00469                 {
00470                     continue;
00471                 }
00472                 //copy the file to the destination
00473                 ret = pal_plat_fsCpFile(pathNameSrc, pathNameDest, currentEntry.fname);
00474                 if (ret != PAL_SUCCESS)
00475                 {
00476                     break;
00477                 }
00478             }
00479             else
00480             {//End of directory reached  without errors break and close directory and exit
00481                 break;
00482             }
00483         }//while()
00484         f_closedir(&src_dh);
00485     }
00486 
00487     return ret;
00488 }
00489 
00490 
00491 PAL_PRIVATE palStatus_t pal_plat_fsCpFile(const char *pathNameSrc,  char *pathNameDest, char * fileName)
00492 {
00493     palStatus_t ret = PAL_SUCCESS;
00494     FIL src_fd, dst_fd;
00495     char * buffer = NULL;
00496     char buffer_name[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; //Buffer for coping the name and folder
00497     size_t bytesCount = 0;
00498     FRESULT status = FR_OK;
00499 
00500     //Add file name to path
00501     pal_plat_addFileNameToPath(pathNameSrc, fileName, buffer_name);
00502     status = f_open(&src_fd, buffer_name, g_platOpenModeConvert[PAL_FS_FLAG_READONLY]);
00503     if (status != FR_OK)
00504     {
00505         ret = pal_plat_errorTranslation(status);
00506     }
00507     else
00508     {
00509         //Add file name to path
00510         pal_plat_addFileNameToPath(pathNameDest, fileName, buffer_name);
00511         status = f_open(&dst_fd, buffer_name, g_platOpenModeConvert[PAL_FS_FLAG_READWRITETRUNC]);
00512         if (status != FR_OK)
00513         {
00514             ret = pal_plat_errorTranslation(status);
00515         }
00516         else
00517         {
00518             buffer = (char*)pal_plat_malloc (PAL_FS_COPY_BUFFER_SIZE);
00519             if (!buffer)
00520             {
00521                 ret = PAL_ERR_RTOS_RESOURCE ;
00522             }
00523         }
00524     }
00525 
00526     if (ret == PAL_SUCCESS)
00527     {
00528         while (1)
00529         {
00530             status = f_read(&src_fd, buffer, PAL_FS_COPY_BUFFER_SIZE, &bytesCount);
00531 
00532             if (status != FR_OK)
00533             {
00534                 break;
00535             }
00536 
00537             //Check if end of file reached
00538             if (bytesCount == 0)
00539             {
00540                 break;
00541             }
00542 
00543             status = f_write(&dst_fd, buffer, bytesCount, &bytesCount);
00544             if (status != FR_OK)
00545             {
00546                 break;
00547             }
00548         }
00549         if (status != FR_OK)
00550         {
00551             ret = pal_plat_errorTranslation(status);
00552         }
00553     }
00554 
00555 
00556 
00557     f_close(&src_fd);
00558     f_close(&dst_fd);
00559     if (buffer)
00560     {
00561         pal_plat_free (buffer);
00562     }
00563     return ret;
00564 }
00565 
00566 const char* pal_plat_fsGetDefaultRootFolder(pal_fsStorageID_t dataID)
00567 {
00568     const char* returnedRoot = NULL;
00569     if (PAL_FS_PARTITION_PRIMARY == dataID)
00570     {
00571         returnedRoot =  PAL_FS_MOUNT_POINT_PRIMARY;
00572     }
00573     else if (PAL_FS_PARTITION_SECONDARY == dataID)
00574     {
00575         returnedRoot =  PAL_FS_MOUNT_POINT_SECONDARY;
00576     }
00577     return returnedRoot;
00578 }
00579 
00580 
00581 PAL_PRIVATE bool pal_plat_findNextFile(DIR *dh, FILINFO  *CurrentEntry)
00582 {
00583     bool ret = true;
00584     bool skip = false;
00585     bool foundFile = false;
00586     FRESULT status;
00587 
00588     do
00589     {
00590         status = f_readdir(dh, CurrentEntry);
00591         if (status == FR_OK)
00592         {
00593             if ((CurrentEntry)->fname[0] == 0)
00594             {//End Of Directory
00595                 ret = true;
00596                 break;
00597             }
00598 
00599             /* Skip the names "." and ".." as we don't want to remove them. also make sure that the current entry point to REGULER file*/
00600             skip = (!strcmp((CurrentEntry)->fname, ".")) || (!strcmp((CurrentEntry)->fname, ".."));
00601             if (skip)
00602             {
00603                 continue;
00604             }
00605             else
00606             {
00607                 foundFile = true;
00608             }
00609         }
00610         else
00611         {//NOT!!! EOF  other error
00612             ret = false;
00613             break; //Break from while
00614         }
00615     }
00616     while((!foundFile) && (ret)); //While file has been found or ret is set to false
00617     return ret;
00618 }
00619 
00620 PAL_PRIVATE palStatus_t pal_plat_addFileNameToPath(const char *pathName, const char * fileName, char * fullPath)
00621 {
00622     palStatus_t ret = PAL_SUCCESS;
00623 
00624     if ((strlen(pathName) >= PAL_MAX_FOLDER_DEPTH_CHAR)  || (strlen(fileName) >= PAL_MAX_FULL_FILE_NAME))
00625     {
00626         ret = PAL_ERR_FS_FILENAME_LENGTH;
00627     }
00628     else if (fullPath)
00629     {
00630         strcpy(fullPath, pathName);
00631         strcat(fullPath, "/");
00632         strcat(fullPath, fileName);
00633     }
00634     else
00635     {
00636         ret = PAL_ERR_RTOS_RESOURCE ;
00637     }
00638     return ret;
00639 }
00640 
00641 
00642 PAL_PRIVATE palStatus_t pal_plat_errorTranslation (int errorOpCode)
00643 {
00644     palStatus_t ret = PAL_SUCCESS;
00645 
00646     switch(errorOpCode)
00647     {
00648     case 0:
00649         break;
00650     case FR_DENIED:
00651     case FR_WRITE_PROTECTED:
00652     case FR_LOCKED:
00653         ret = PAL_ERR_FS_ACCESS_DENIED;
00654         break;
00655 
00656     case FR_NOT_READY :
00657         ret = PAL_ERR_FS_BUSY;
00658         break;
00659 
00660     case FR_EXIST:
00661         ret = PAL_ERR_FS_NAME_ALREADY_EXIST;
00662         break;
00663 
00664     case FR_INVALID_NAME:
00665     case FR_INVALID_OBJECT:
00666     case FR_INVALID_DRIVE:
00667         ret = PAL_ERR_FS_INVALID_ARGUMENT;
00668         break;
00669 
00670     case  FR_NO_FILE:
00671         ret = PAL_ERR_FS_NO_FILE;
00672         break;
00673 
00674     case FR_NO_PATH:
00675         ret = PAL_ERR_FS_NO_PATH;
00676         break;
00677 
00678     default:
00679         ret = PAL_ERR_FS_ERROR;
00680         break;
00681     }
00682     return ret;
00683 }
00684 
00685 
00686 size_t pal_plat_fsSizeCheck(const char *stringToChk)
00687 {
00688     size_t length = 0;
00689     length = strlen(stringToChk);
00690     return length;
00691 }
00692 
00693 
00694 
00695 palStatus_t pal_plat_fsFormat(pal_fsStorageID_t dataID)
00696 {
00697     const char* partitionNames[] ={
00698                                     PAL_FS_MOUNT_POINT_PRIMARY,
00699                                     PAL_FS_MOUNT_POINT_SECONDARY
00700                                    };
00701     palStatus_t result = PAL_SUCCESS;
00702     const char* partName = partitionNames[dataID];
00703     FRESULT res = f_mkfs(partName, 0, 0);
00704     if (FR_OK != res)
00705     {
00706         result = PAL_ERR_FS_ERROR;
00707     }
00708     return result;
00709 }