FreeCalypso > hg > tcs211-fcmodem
view g23m/condat/com/src/driver/ffs_pc.c @ 21:0f832c4c3db8 default tip
README for the tcs211-fcmodem tree
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 23 Sep 2016 19:58:17 +0000 |
parents | 509db1a7b7b8 |
children |
line wrap: on
line source
/********************************************************************************/ /* */ /* 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); }