FreeCalypso > hg > tcs211-l1-reconst
diff g23m/condat/com/src/driver/ffs_pc.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/g23m/condat/com/src/driver/ffs_pc.c Mon Jun 01 03:24:05 2015 +0000 @@ -0,0 +1,1475 @@ +/********************************************************************************/ +/* */ +/* File Name: ffs_pc.c */ +/* */ +/* Purpose: This file contains the internal functions related to */ +/* the Flash File System. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 02/27/02 Pascal Pompei */ +/* - Create. */ +/* */ +/* (C) Copyright 2002 by Texas Instruments Incorporated, All Rights Reserved. */ +/* */ +/********************************************************************************/ + +#include "ffs_pc_api.h" + +/********************************* NAME LENGTHS *********************************/ +/* */ +/* Define the maximum lengths. */ +#define FFS_MAX_PATH_LENGTH (MAX_PATH) +#define FFS_MAX_OBJECT_LENGTH (20) + + +/*************************** INTERNAL FILE DESCRIPTOR ***************************/ +/* */ +/* Define the internal file descriptor. */ +/* */ +/* __ Open the file for appending. */ +/* | __ File handle (30 bits). */ +/* __|______________________________|_____________________________ */ +/* | ¦ ¦ | */ +/* |0¦ ¦ | */ +/* |_¦_¦_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._| */ +typedef union +{ + INT32 fd; + struct + { + INT32 handle : 30; + INT32 append : 1; + } ifd; +} T_FFS_IFD; + + +/* Define the directory nesting depth. */ +#define FFS_DIR_NESTING_DEPTH (0x06) + +/* Define the directory dedicated to the Flash File System. */ +#define FFS_DIR ("C:\\FFS") + + +/******************** GLOBAL FLASH FILE SYSTEM CONTROL BLOCK ********************/ +/* */ +/* Define a global structure used to gather information related to the 'Global */ +/* Flash File System Control Block'. */ +typedef struct +{ + BOOLEAN is_running; /* Indicates */ + /* whether the */ + /* Flash File */ + /* System is */ + /* running. */ + char current_working_dir[FFS_MAX_PATH_LENGTH]; /* Indicates the */ + /* current */ + /* working */ + /* directory. */ +} T_FFS_CTRL_BLK; + + +/******************** GLOBAL FLASH FILE SYSTEM CONTROL BLOCK ********************/ +/* */ +T_FFS_CTRL_BLK gbl_ffs_ctrl_blk; + +/* Define a pointer to the 'Global Flash File System Control Block'. */ +T_FFS_CTRL_BLK *gbl_ffs_ctrl_blk_p = NULL; + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_init_working_folder */ +/* */ +/* Purpose: This function sets the working directory up. */ +/* */ +/* Input Parameter: None. */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 02/28/02 Pascal Pompei */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_init_working_folder (void) +{ + +/******************** ffs_init_working_folder function begins *******************/ + + /* First, check whether the current working directory matches the reference */ + /* one. Otherwise, create the reference directory. */ + + strcpy (gbl_ffs_ctrl_blk_p->current_working_dir, FFS_DIR); + + if ((CreateDirectory (TEXT(gbl_ffs_ctrl_blk_p->current_working_dir), \ + NULL) == FALSE) && \ + (GetLastError () != ERROR_ALREADY_EXISTS)) + { + return (EFFS_DRIVER); + } + + return (EFFS_OK); + +} /******************* End of ffs_init_working_folder function ******************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_is_valid_object_name */ +/* */ +/* Purpose: This function checks whether the name of an object is */ +/* valid, according to the Microsoft® Win32® Programmer's */ +/* Reference. */ +/* */ +/* Input Parameter: */ +/* object_name_p - Points to the name of the object to check */ +/* (0-terminated string). */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: None. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 06/27/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_is_valid_object_name (const char *object_name_p) +{ + /* Declare local variables. */ + DWORD object_count = 0x00000000; + DWORD path_count = 0x00000000; + +/******************* ffs_is_valid_object_name function begins *******************/ + + /* First, check for the leading '/' character. */ + if (object_name_p[path_count++] != '/') + { + return (EFFS_BADNAME); + } + + /* Then, check for invalid characters or too long object names. */ + for (; + path_count <= FFS_MAX_PATH_LENGTH; + path_count++) + { + + /* Check for invalid characters. */ + if (((object_name_p[path_count] >= 'a') && (object_name_p[path_count] <= 'z')) || \ + ((object_name_p[path_count] >= 'A') && (object_name_p[path_count] <= 'Z')) || \ + ((object_name_p[path_count] >= '0') && (object_name_p[path_count] <= '9')) || \ + (object_name_p[path_count] == '#') || \ + (object_name_p[path_count] == '$') || \ + (object_name_p[path_count] == '%') || \ + (object_name_p[path_count] == '+') || \ + (object_name_p[path_count] == '-') || \ + (object_name_p[path_count] == '.') || \ + (object_name_p[path_count] == '_')) + { + + /* Check for too long object names. */ + if (++object_count > FFS_MAX_OBJECT_LENGTH) + { + return (EFFS_NAMETOOLONG); + } + continue; + } + + /* Proceed with the next object name. */ + if (object_name_p[path_count] == '/') + { + + /* Check for empty object names. */ + if (object_count == 0x00000000) + { + break; + } + object_count = 0x00000000; + continue; + } + break; + } + + /* Check for the ending '/' character. */ + if ((object_name_p[path_count] == '\x00') && \ + (object_count == 0x00000000)) + { + return (EFFS_NOTADIR); + } + + /* Report an error whether an object name contains some illegal characters. */ + if ((object_name_p[path_count] != '\x00') || \ + (object_count == 0x00000000)) + { + return (EFFS_BADNAME); + } + return (EFFS_OK); + +} /****************** End of ffs_is_valid_object_name function ******************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_convert_to_win32_filename */ +/* */ +/* Purpose: This function converts filenames in accordance with */ +/* the Microsoft® Win32® Programmer's Reference. */ +/* */ +/* Input Parameter: */ +/* filename_p - Points to the filename to convert (0-terminated */ +/* string). */ +/* */ +/* Output Parameter: */ +/* win32_filename_p - Points to the filename as defined in the */ +/* Microsoft® Win32® Programmer's Reference. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 06/27/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_convert_to_win32_filename (const char *filename_p, + char win32_filename_p[FFS_MAX_PATH_LENGTH]) +{ + /* Declare local variables. */ + DWORD filename_len = 0x00000000; + DWORD pathname_len = 0x00000000; + +/***************** ffs_convert_to_win32_filename function begins ****************/ + + /* Get the lengths of both filenames. */ + filename_len = strlen (filename_p); + pathname_len = strlen (gbl_ffs_ctrl_blk_p->current_working_dir); + + /* Convert the filename in accordance with the Microsoft® Win32® */ + /* Programmer's Reference. Abort whether the filename is too long. */ + if ((pathname_len + filename_len + 0x00000001) > FFS_MAX_PATH_LENGTH) + { + return (EFFS_NAMETOOLONG); + } + (void) memcpy (win32_filename_p, + gbl_ffs_ctrl_blk_p->current_working_dir, + pathname_len); + (void) memcpy (win32_filename_p + pathname_len, + filename_p, + filename_len); + win32_filename_p[pathname_len + filename_len] = '\x00'; + return (EFFS_OK); + +} /**************** End of ffs_convert_to_win32_filename function ***************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_open */ +/* */ +/* Purpose: This function opens or creates a file. */ +/* */ +/* Input Parameters: */ +/* pathname_p - Points to the name of the file to open or create */ +/* (0-terminated string). */ +/* flags - Specifies the modes used to open the file. */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: The append concept while opening files is not */ +/* supported, according to the Microsoft® Win32® */ +/* Programmer's Reference. */ +/* */ +/* Revision History: */ +/* 06/27/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_FD ffs_open (const char *pathname_p, + T_FFS_OPEN_FLAGS flags) +{ + /* Declare local variables. */ + char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; + DWORD desired_access = GENERIC_WRITE; + DWORD creation_distribution = OPEN_EXISTING; + HANDLE handle = INVALID_HANDLE_VALUE; + T_FFS_IFD ifd = {0x00000000}; + T_FFS_RET return_status = EFFS_OK; + +/*************************** ffs_open function begins ***************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, convert the filename as defined in the Microsoft® Win32® */ + /* Programmer's Reference. Abort whether any error occurred. */ + if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ + ((return_status = ffs_convert_to_win32_filename (pathname_p, \ + win32_pathname_p)) != EFFS_OK)) + { + return (return_status); + } + + /* Convert flags as defined in the Microsoft® Win32® Programmer's */ + /* Reference. */ + switch (flags & FFS_O_RDWR) + { + + /* The file is opened as 'read-only'. */ + case FFS_O_RDONLY: + { + + /* 'Read-only' must not be combined with any other options. */ + if (flags != FFS_O_RDONLY) + { + return (EFFS_INVALID); + } + desired_access = GENERIC_READ; + break; + } + + /* The file is opened as 'read-write'. */ + case FFS_O_RDWR: + { + desired_access |= GENERIC_READ; + } + + /* The file is opened as 'write-only'. */ + case FFS_O_WRONLY: + { + switch (flags & ~FFS_O_RDWR) + { + + /* Create the file if it does not exist, otherwise truncate */ + /* it. */ + case (FFS_O_CREATE | FFS_O_APPEND | FFS_O_TRUNC): + { + (ifd.ifd).append = TRUE; + } + case (FFS_O_CREATE | FFS_O_TRUNC): + { + creation_distribution = CREATE_ALWAYS; + break; + } + + /* Create the file if it does not exist, otherwise open it */ + /* for appending. */ + case (FFS_O_CREATE | FFS_O_APPEND): + { + (ifd.ifd).append = TRUE; + creation_distribution = OPEN_ALWAYS; + break; + } + + /* Create the file if it does not exist, otherwise the */ + /* function fails. */ + case (FFS_O_CREATE | FFS_O_EXCL): + { + creation_distribution = CREATE_NEW; + break; + } + + /* Create the file if it does not exist, otherwise open it. */ + case FFS_O_CREATE: + { + creation_distribution = OPEN_ALWAYS; + break; + } + + /* Truncate the file if it already exists, otherwise the */ + /* function fails. */ + case (FFS_O_APPEND | FFS_O_TRUNC): + { + (ifd.ifd).append = TRUE; + } + case FFS_O_TRUNC: + { + creation_distribution = TRUNCATE_EXISTING; + break; + } + + /* Open the file for appending if it already exists, */ + /* otherwise the function fails. */ + case FFS_O_APPEND: + { + (ifd.ifd).append = TRUE; + break; + } + default: + { + break; + } + } + break; + } + default: + { + return (EFFS_INVALID); + } + } + + /* Open/create the file as specified. */ + if (((handle = CreateFile (win32_pathname_p, \ + desired_access, \ + 0x0000, \ + NULL, \ + creation_distribution, \ + FILE_ATTRIBUTE_NORMAL, \ + NULL)) == INVALID_HANDLE_VALUE) || \ + (((ifd.ifd).append) && \ + (SetFilePointer (handle, \ + 0x00000000, \ + NULL, \ + FILE_END) == 0xFFFFFFFF))) + { + + /* Declare a local block variable. */ + DWORD error = NO_ERROR; + + /* Get the error code. */ + error = GetLastError (); + + /* If the file handle is valid, then close the file first. */ + if (handle != INVALID_HANDLE_VALUE) + { + (void) CloseHandle (handle); + } + switch (error) + { + + /* Unable to create a file when it already exists. */ + case ERROR_ALREADY_EXISTS: + + /* The file exists. */ + case ERROR_FILE_EXISTS: + { + return (EFFS_EXISTS); + } + + /* The directory name is invalid. */ + case ERROR_DIRECTORY: + + /* Unable to find the file specified. */ + case ERROR_FILE_NOT_FOUND: + { + return (EFFS_NOTFOUND); + } + + /* Unable to open the file because too many files are currently */ + /* open. */ + case ERROR_TOO_MANY_OPEN_FILES: + { + return (EFFS_NUMFD); + } + + /* The disk is full. */ + case ERROR_HANDLE_DISK_FULL: + { + return (EFFS_FSFULL); + } + + /* The filename or directory name is syntactically incorrect. */ + case ERROR_INVALID_NAME: + { + return (EFFS_BADNAME); + } + default: + { + return (EFFS_DRIVER); + } + } + } + + /* If the file handle is invalid, then close the file. */ + if (((INT32) (handle)) & 0xC0000000) + { + (void) CloseHandle (handle); + return (EFFS_NUMFD); + } + + /* Get the file handle. */ + ifd.fd |= (INT32) (handle); + return ((T_FFS_FD) (ifd.fd)); + +} /************************** End of ffs_open function **************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_close */ +/* */ +/* Purpose: This function closes an open file. */ +/* */ +/* Input Parameter: */ +/* fd - Specifies the file descriptor associated with the */ +/* file to close. */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 06/27/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_close (T_FFS_FD fd) +{ + /* Declare a local variable. */ + T_FFS_IFD ifd = {0x00000000}; + +/*************************** ffs_close function begins **************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, get the file handle. */ + ifd.fd = fd; + + /* At last, close the file. */ + if (CloseHandle ((HANDLE) ((ifd.ifd).handle)) == FALSE) + { + return (EFFS_BADFD); + } + return (EFFS_OK); + +} /************************** End of ffs_close function *************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_write */ +/* */ +/* Purpose: This function writes data to an open file. */ +/* */ +/* Input Parameters: */ +/* fd - Specifies the file descriptor associated with the */ +/* open file. */ +/* buffer_p - Points to the buffer containing the data to be */ +/* written to the file. */ +/* size - Specifies the number of bytes to write to the */ +/* file. */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: This function is not responsible for (de)allocating */ +/* the buffer containing the data to be written to the */ +/* file. */ +/* */ +/* Revision History: */ +/* 06/29/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_SIZE ffs_write (T_FFS_FD fd, + void *buffer_p, + T_FFS_SIZE size) +{ + /* Declare local variables. */ + DWORD bytes_written = 0x00000000; + T_FFS_IFD ifd = {0x00000000}; + +/*************************** ffs_write function begins **************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, get the file handle. */ + ifd.fd = fd; + + /* Then, check whether the file is opened for appending. Indeed, opening a */ + /* file with append mode shall cause all subsequent writes to the file to */ + /* be forced to end-of-file (EOF) position, regardless of intervening calls */ + /* to ffs_seek (). */ + if (((ifd.ifd).append) && \ + (SetFilePointer ((HANDLE) ((ifd.ifd).handle), \ + 0x00000000, \ + NULL, \ + FILE_END) == 0xFFFFFFFF)) + { + return (EFFS_BADFD); + } + + /* At last, write data to the file. */ + if (WriteFile ((HANDLE) ((ifd.ifd).handle), \ + buffer_p, \ + size, \ + &bytes_written, \ + NULL) == FALSE) + { + + /* Get the error code. */ + switch (GetLastError ()) + { + + /* Access denied. */ + case ERROR_ACCESS_DENIED: + { + return (EFFS_BADOP); + } + + /* The disk is full. */ + case ERROR_HANDLE_DISK_FULL: + { + return (EFFS_NOSPACE); + } + default: + { + return (EFFS_BADFD); + } + } + } + return (bytes_written); + +} /************************** End of ffs_write function *************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_read */ +/* */ +/* Purpose: This function reads data from an open file. */ +/* */ +/* Input Parameters: */ +/* fd - Specifies the file descriptor associated with the */ +/* open file. */ +/* buffer_p - Points to the buffer that receives the data read */ +/* from the file. */ +/* size - Specifies the number of bytes to be read from the */ +/* file. */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: This function is not responsible for (de)allocating */ +/* the buffer that receives the data read from the file. */ +/* */ +/* Revision History: */ +/* 06/29/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_SIZE ffs_read (T_FFS_FD fd, + void *buffer_p, + T_FFS_SIZE size) +{ + /* Declare local variables. */ + DWORD bytes_read = 0x00000000; + T_FFS_IFD ifd = {0x00000000}; + +/*************************** ffs_read function begins ***************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, get the file handle. */ + ifd.fd = fd; + + /* At last, read data from the file. */ + if (ReadFile ((HANDLE) ((ifd.ifd).handle), \ + buffer_p, \ + size, \ + &bytes_read, \ + NULL) == FALSE) + { + return (EFFS_BADFD); + } + return (bytes_read); + +} /************************** End of ffs_read function **************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_seek */ +/* */ +/* Purpose: This function moves the file pointer of an open file. */ +/* */ +/* Input Parameters: */ +/* fd - Specifies the file descriptor associated with the */ +/* open file. */ +/* offset - Specifies the number of bytes to move file */ +/* pointer. */ +/* whence - Specifies the starting point for the file pointer */ +/* move. */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: This function does not allow the file pointer to be */ +/* set beyond the end-of-file (EOF) position, in contrary */ +/* to the Microsoft® Win32® Programmer's Reference. */ +/* */ +/* Revision History: */ +/* 06/29/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_SIZE ffs_seek (T_FFS_FD fd, + T_FFS_SIZE offset, + T_FFS_WHENCE whence) +{ + /* Declare local variables. */ + DWORD file_size = 0x00000000; + DWORD new_file_pointer = 0x00000000; + T_FFS_IFD ifd = {0x00000000}; + +/*************************** ffs_seek function begins ***************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, get the file handle. */ + ifd.fd = fd; + + /* At last, move the file pointer and get the size of the file. */ + if (((new_file_pointer = SetFilePointer ((HANDLE) ((ifd.ifd).handle), \ + offset, \ + NULL, \ + whence)) != 0xFFFFFFFF) && \ + ((file_size = GetFileSize ((HANDLE) ((ifd.ifd).handle), \ + NULL)) != 0xFFFFFFFF)) + { + + /* Check whether the file pointer is beyond the end-of-file (EOF) */ + /* position. */ + if (new_file_pointer <= file_size) + { + return (new_file_pointer); + } + + /* In such a case, back to the former position. */ + if (SetFilePointer ((HANDLE) ((ifd.ifd).handle), \ + -offset, \ + NULL, \ + FILE_CURRENT) != 0xFFFFFFFF) + { + return (EFFS_INVALID); + } + } + + /* Get the error code. */ + switch (GetLastError ()) + { + + /* Invalid parameters. */ + case ERROR_INVALID_PARAMETER: + + /* Unable to move the file pointer before the beginning of the file. */ + case ERROR_NEGATIVE_SEEK: + + /* Unable to set the file pointer on the specified file. */ + case ERROR_SEEK_ON_DEVICE: + { + return (EFFS_INVALID); + } + default: + { + break; + } + } + return (EFFS_BADFD); + +} /************************** End of ffs_seek function **************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_ftruncate */ +/* */ +/* Purpose: This function truncates an open file by moving the */ +/* end-of-file (EOF) position. */ +/* */ +/* Input Parameters: */ +/* fd - Specifies the file descriptor associated with the */ +/* open file. */ +/* length - Specifies the number of bytes to move file */ +/* pointer. */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: This function does not allow the file pointer to be */ +/* set beyond the end-of-file (EOF) position, in contrary */ +/* to the Microsoft® Win32® Programmer's Reference. */ +/* */ +/* Revision History: */ +/* 02/13/02 Pascal Pompei */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_ftruncate (T_FFS_FD fd, + T_FFS_OFFSET length) +{ + /* Declare a local variable. */ + T_FFS_IFD ifd = {0x00000000}; + +/************************* ffs_ftruncate function begins ************************/ + + /* First, check whether the size is greater than the current file pointer */ + /* position. */ + if (length < (T_FFS_OFFSET) (ffs_seek (fd, \ + 0, \ + FFS_SEEK_CUR))) + { + return (EFFS_INVALID); + } + + /* Move the end-of-file (EOF) position. */ + switch (ffs_seek (fd, \ + length, \ + FFS_SEEK_SET)) + { + + /* Unable to move the file pointer beyond the end-of-file (EOF) */ + /* position. */ + case EFFS_INVALID: + { + return (EFFS_OK); + } + + /* File not found. */ + case EFFS_BADFD: + { + return (EFFS_BADFD); + } + default: + { + break; + } + } + + /* Then, get the file handle. */ + ifd.fd = fd; + + /* At last, set the current file pointer as the end-of-file (EOF) position. */ + if (SetEndOfFile ((HANDLE) ((ifd.ifd).handle)) == FALSE) + { + return (EFFS_INVALID); + } + return (EFFS_OK); + +} /************************ End of ffs_ftruncate function ***********************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_stat */ +/* */ +/* Purpose: This function gets information (meta-data) about a */ +/* object. */ +/* */ +/* Input Parameter: */ +/* pathname_p - Points to the name of the file or directory */ +/* (0-terminated string). */ +/* */ +/* Output Parameter: */ +/* stat_p - Points to information (meta-data) about the */ +/* object. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 02/28/01 Pascal Pompei */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_stat (const char *pathname_p, + T_FFS_STAT *stat_p) +{ + /* Declare local variables. */ + char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; + HANDLE search_handle = INVALID_HANDLE_VALUE; + T_FFS_RET return_status = EFFS_OK; + WIN32_FIND_DATA find_data; + +/*************************** ffs_stat function begins ***************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, convert the name of the file or the directory as defined in the */ + /* Microsoft® Win32® Programmer's Reference. Abort whether any error */ + /* occurred. */ + if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ + ((return_status = ffs_convert_to_win32_filename (pathname_p, \ + win32_pathname_p)) != EFFS_OK)) + { + return (return_status); + } + + /* Search for a file or a directory whose name matches the specified one. */ + /* Abort whether the file or directory does not exist. */ + if (((search_handle = FindFirstFile (win32_pathname_p, \ + &find_data)) != INVALID_HANDLE_VALUE) && \ + (find_data.dwFileAttributes != 0xFFFFFFFF)) + { + + /* Get information depending on attributes for the the file or */ + /* directory. */ + if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + stat_p->type = OT_DIR; + stat_p->size = 0x00000000; + } + else + { + stat_p->type = OT_FILE; + stat_p->size = find_data.nFileSizeLow; + } + + /* Close the search handle. */ + (void) FindClose (search_handle); + return (EFFS_OK); + } + return (EFFS_NOTFOUND); + +} /************************** End of ffs_stat function **************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_remove */ +/* */ +/* Purpose: This function removes a file or a directory. */ +/* */ +/* Input Parameter: */ +/* pathname_p - Points to the name of the file or directory to */ +/* remove (0-terminated string). */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: The variable callback_p is a pointer to a function */ +/* that follows the C Calling Convention. However, such a */ +/* variable has to be redefined as a pointer to a */ +/* function that follows the Standard Calling Convention */ +/* by using _stdcall (avoid 'error C2152: '=' : pointers */ +/* to functions with different attributes' error */ +/* message). */ +/* */ +/* Revision History: */ +/* 06/29/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_remove (const char *pathname_p) +{ + /* Declare local variables. */ + BOOL (_stdcall *callback_p) (LPCTSTR) = DeleteFile; + char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; + DWORD attributes = 0xFFFFFFFF; + T_FFS_RET return_status = EFFS_OK; + +/************************** ffs_remove function begins **************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, convert the name of the file or the directory as defined in the */ + /* Microsoft® Win32® Programmer's Reference. Abort whether any error */ + /* occurred. */ + if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ + ((return_status = ffs_convert_to_win32_filename (pathname_p, \ + win32_pathname_p)) != EFFS_OK)) + { + return (return_status); + } + + /* Get attributes for the specified file or directory. */ + if ((attributes = GetFileAttributes (win32_pathname_p)) == 0xFFFFFFFF) + { + return (EFFS_NOTFOUND); + } + + /* Check whether the object is a directory. */ + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + { + callback_p = RemoveDirectory; + } + + /* Remove the file or the directory. */ + if ((*callback_p) (win32_pathname_p) == FALSE) + { + + /* Get the error code. */ + switch (GetLastError ()) + { + + /* Access denied. */ + case ERROR_ACCESS_DENIED: + + /* Unable to access the file because it is being used by another */ + /* process. */ + case ERROR_SHARING_VIOLATION: + { + return (EFFS_LOCKED); + } + + /* The directory is not empty. */ + case ERROR_DIR_NOT_EMPTY: + { + return (EFFS_DIRNOTEMPTY); + } + default: + { + return (EFFS_DRIVER); + } + } + } + return (EFFS_OK); + +} /************************* End of ffs_remove function *************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_mkdir */ +/* */ +/* Purpose: This function creates a new directory. */ +/* */ +/* Input Parameter: */ +/* pathname_p - Points to the name of the directory to create */ +/* (0-terminated string). */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 06/29/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_mkdir (const char *pathname_p) +{ + /* Declare local variables. */ + char *object_name_p = NULL; + char pathname_parsed_p[FFS_MAX_PATH_LENGTH] = ""; + char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; + DWORD dir_nesting_depth = 0x00000000; + T_FFS_RET return_status = EFFS_OK; + +/*************************** ffs_mkdir function begins **************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, convert the name of the directory as defined in the Microsoft® */ + /* Win32® Programmer's Reference. Abort whether any error occurred. */ + if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ + ((return_status = ffs_convert_to_win32_filename (pathname_p, \ + win32_pathname_p)) != EFFS_OK)) + { + return (return_status); + } + + /* At last, check whether the directory nesting depth is exceeded. Thus, */ + /* search for '/' characters from the end of the name of the directory. */ + (void) strcpy (pathname_parsed_p, + pathname_p); + while (((object_name_p = strrchr (pathname_parsed_p, \ + '/')) != NULL) && \ + (dir_nesting_depth <= FFS_DIR_NESTING_DEPTH)) + { + + /* Check for '/..' object names. */ + if (strcmp (object_name_p, \ + "/..") == 0x00000000) + { + dir_nesting_depth--; + } + else + { + + /* Check for '/.' object names. */ + if (strcmp (object_name_p, \ + "/.") != 0x00000000) + { + dir_nesting_depth++; + } + } + + /* Truncate the name of the directory in order to search for other '/' */ + /* characters backwards. */ + pathname_parsed_p[object_name_p - pathname_parsed_p] = '\x00'; + } + + /* Abort whether the directory nesting depth is exceeded. */ + if (dir_nesting_depth > FFS_DIR_NESTING_DEPTH) + { + return (EFFS_PATHTOODEEP); + } + + /* Create the new directory. */ + if (CreateDirectory (win32_pathname_p, \ + NULL) == FALSE) + { + + /* Get the error code. */ + switch (GetLastError ()) + { + + /* The directory already exists. */ + case ERROR_ALREADY_EXISTS: + { + return (EFFS_EXISTS); + } + + /* Unable to find the specified directory. */ + case ERROR_PATH_NOT_FOUND: + { + return (EFFS_NOTADIR); + } + default: + { + return (EFFS_DRIVER); + } + } + } + return (EFFS_OK); + +} /************************** End of ffs_mkdir function *************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_opendir */ +/* */ +/* Purpose: This function opens a directory and returns the number */ +/* of objects included into. */ +/* */ +/* Input Parameter: */ +/* pathname_p - Points to the name of the directory to open */ +/* (0-terminated string). */ +/* */ +/* Output Parameter: */ +/* dir_p - Points to information about the directory (refer */ +/* to ffs_readdir (···)). */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 06/29/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_SIZE ffs_opendir (const char *pathname_p, + T_FFS_DIR *dir_p) +{ + /* Declare local variables. */ + char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; + T_FFS_RET return_status = EFFS_OK; + +/************************** ffs_opendir function begins *************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, convert the name of the directory as defined in the Microsoft® */ + /* Win32® Programmer's Reference. Abort whether any error occurred. */ + if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ + ((return_status = ffs_convert_to_win32_filename (pathname_p, \ + win32_pathname_p)) != EFFS_OK)) + { + return (return_status); + } + + /* Search for a directory whose name matches the specified one. Abort */ + /* whether the directory does not exist. */ + if (((dir_p->search_handle = FindFirstFile (strcat (win32_pathname_p, \ + "//*"), \ + &(dir_p->find_data))) != INVALID_HANDLE_VALUE) && \ + ((dir_p->find_data).dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + + /* Declare local block variables. */ + DWORD object_count = 0x00000000; + WIN32_FIND_DATA find_data; + + /* Go downward through the directory tree. */ + while (FindNextFile (dir_p->search_handle, \ + &find_data) == TRUE) + { + + /* Disregard '.' and '..' subdirectories. */ + if (find_data.cFileName[0] == '.') + { + continue; + } + object_count++; + } + + /* Close the search handle since no more objects left. */ + if (object_count > 0x00000000) + { + (void) FindClose (dir_p->search_handle); + + /* Back to the first object included in the directory. */ + dir_p->search_handle = FindFirstFile (win32_pathname_p, + &(dir_p->find_data)); + } + return (object_count); + } + return (EFFS_NOTFOUND); + +} /************************* End of ffs_opendir function ************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_readdir */ +/* */ +/* Purpose: This function gets the next entry from a directory. */ +/* */ +/* Input Parameters: */ +/* dir_p - Points to information about the directory (refer */ +/* to ffs_opendir (···)). */ +/* buffer_p - Points to the buffer that receives the name of */ +/* the next entry. */ +/* size - Specifies the number of bytes of the buffer that */ +/* receives the name of the next entry. */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: This function is not responsible for (de)allocating */ +/* the buffer that receives the name of the next entry. */ +/* */ +/* Revision History: */ +/* 06/29/01 David Lamy-Charrier */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_SIZE ffs_readdir (T_FFS_DIR *dir_p, + char *buffer_p, + T_FFS_SIZE size) +{ + +/************************** ffs_readdir function begins *************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Go downward through the directory tree. */ + while (FindNextFile (dir_p->search_handle, \ + &(dir_p->find_data)) == TRUE) + { + + /* Disregard '.' and '..' subdirectories. */ + if ((dir_p->find_data).cFileName[0] == '.') + { + continue; + } + + /* Copy the name of this entry. */ + (void) strncpy (buffer_p, \ + (dir_p->find_data).cFileName, \ + size); + return (strlen ((dir_p->find_data).cFileName)); + } + + /* Close the search handle since no more objects left. */ + if (GetLastError () == ERROR_NO_MORE_FILES) + { + (void) FindClose (dir_p->search_handle); + } + return (0x00000000); + +} /************************* End of ffs_readdir function ************************/ + + +/********************************************************************************/ +/* */ +/* Function Name: ffs_rename */ +/* */ +/* Purpose: This function renames a file or a directory. */ +/* */ +/* Input Parameters: */ +/* old_pathname_p - Points to the name of the existing file or */ +/* directory (0-terminated string). */ +/* new_pathname_p - Points to the new name for the file or the */ +/* directory (0-terminated string). */ +/* */ +/* Output Parameter: None. */ +/* */ +/* Global Parameter: */ +/* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ +/* Block'. */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 02/13/02 Pascal Pompei */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_FFS_RET ffs_rename (const char *old_pathname_p, + const char *new_pathname_p) +{ + /* Declare local variables. */ + char old_win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; + char new_win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; + T_FFS_RET return_status = EFFS_OK; + +/************************** ffs_rename function begins **************************/ + + /* First, check whether the Flash File System is running. */ + if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) + { + return (EFFS_AGAIN); + } + + /* Then, convert both pathnames as defined in the Microsoft® Win32® */ + /* Programmer's Reference. Abort whether any error occurred. */ + if (((return_status = ffs_is_valid_object_name (old_pathname_p)) != EFFS_OK) || \ + ((return_status = ffs_is_valid_object_name (new_pathname_p)) != EFFS_OK) || \ + ((return_status = ffs_convert_to_win32_filename (old_pathname_p, \ + old_win32_pathname_p)) != EFFS_OK) || \ + ((return_status = ffs_convert_to_win32_filename (new_pathname_p, \ + new_win32_pathname_p)) != EFFS_OK)) + { + return (return_status); + } + + /* Rename the file or the directory. */ + if (MoveFile (old_win32_pathname_p, \ + new_win32_pathname_p) == FALSE) + { + + /* Get the error code. */ + switch (GetLastError ()) + { + + /* File or directory already exists. */ + case ERROR_ALREADY_EXISTS: + + /* The file exists. */ + case ERROR_FILE_EXISTS: + { + return (EFFS_EXISTS); + } + + /* Access denied. */ + case ERROR_ACCESS_DENIED: + + /* Unable to access the file because it is being used by another */ + /* process. */ + case ERROR_SHARING_VIOLATION: + { + return (EFFS_LOCKED); + } + default: + { + return (EFFS_NOTFOUND); + } + } + } + return (EFFS_OK); + +} /************************* End of ffs_rename function *************************/ + + +/* SAMIR + Function taken from ffs_env.c +*/ +T_FFS_SIZE ffs_init (void) +{ + +/*************************** ffs_init function begins ***************************/ + + gbl_ffs_ctrl_blk_p = &gbl_ffs_ctrl_blk; + + /* Initialize the current working directory. */ + if (ffs_init_working_folder () != EFFS_OK) + { + return (EFFS_AGAIN); + } + + /* State the Flash File System as running. */ + gbl_ffs_ctrl_blk_p->is_running = TRUE; + + return (EFFS_OK); + +} \ No newline at end of file