| 1 |  |  | /**************************************************************************/ | 
    
    | 2 |  |  | /*                                                                        */ | 
    
    | 3 |  |  | /*       Copyright (c) Microsoft Corporation. All rights reserved.        */ | 
    
    | 4 |  |  | /*                                                                        */ | 
    
    | 5 |  |  | /*       This software is licensed under the Microsoft Software License   */ | 
    
    | 6 |  |  | /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */ | 
    
    | 7 |  |  | /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */ | 
    
    | 8 |  |  | /*       and in the root directory of this software.                      */ | 
    
    | 9 |  |  | /*                                                                        */ | 
    
    | 10 |  |  | /**************************************************************************/ | 
    
    | 11 |  |  |  | 
    
    | 12 |  |  |  | 
    
    | 13 |  |  | /**************************************************************************/ | 
    
    | 14 |  |  | /**************************************************************************/ | 
    
    | 15 |  |  | /**                                                                       */ | 
    
    | 16 |  |  | /** FileX Component                                                       */ | 
    
    | 17 |  |  | /**                                                                       */ | 
    
    | 18 |  |  | /**   File                                                                */ | 
    
    | 19 |  |  | /**                                                                       */ | 
    
    | 20 |  |  | /**************************************************************************/ | 
    
    | 21 |  |  | /**************************************************************************/ | 
    
    | 22 |  |  |  | 
    
    | 23 |  |  | #define FX_SOURCE_CODE | 
    
    | 24 |  |  |  | 
    
    | 25 |  |  |  | 
    
    | 26 |  |  | /* Include necessary system files.  */ | 
    
    | 27 |  |  |  | 
    
    | 28 |  |  | #include "fx_api.h" | 
    
    | 29 |  |  | #include "fx_system.h" | 
    
    | 30 |  |  | #include "fx_directory.h" | 
    
    | 31 |  |  | #include "fx_file.h" | 
    
    | 32 |  |  | #include "fx_utility.h" | 
    
    | 33 |  |  | #ifdef FX_ENABLE_FAULT_TOLERANT | 
    
    | 34 |  |  | #include "fx_fault_tolerant.h" | 
    
    | 35 |  |  | #endif /* FX_ENABLE_FAULT_TOLERANT */ | 
    
    | 36 |  |  |  | 
    
    | 37 |  |  |  | 
    
    | 38 |  |  | /**************************************************************************/ | 
    
    | 39 |  |  | /*                                                                        */ | 
    
    | 40 |  |  | /*  FUNCTION                                               RELEASE        */ | 
    
    | 41 |  |  | /*                                                                        */ | 
    
    | 42 |  |  | /*    _fx_file_attributes_set                             PORTABLE C      */ | 
    
    | 43 |  |  | /*                                                           6.1          */ | 
    
    | 44 |  |  | /*  AUTHOR                                                                */ | 
    
    | 45 |  |  | /*                                                                        */ | 
    
    | 46 |  |  | /*    William E. Lamie, Microsoft Corporation                             */ | 
    
    | 47 |  |  | /*                                                                        */ | 
    
    | 48 |  |  | /*  DESCRIPTION                                                           */ | 
    
    | 49 |  |  | /*                                                                        */ | 
    
    | 50 |  |  | /*    This function first attempts to find the specified file.  If found, */ | 
    
    | 51 |  |  | /*    the attribute set request is valid and the directory entry will be  */ | 
    
    | 52 |  |  | /*    modified with the new attributes.  Otherwise, if the file is not    */ | 
    
    | 53 |  |  | /*    found, the appropriate error code is returned to the caller.        */ | 
    
    | 54 |  |  | /*                                                                        */ | 
    
    | 55 |  |  | /*  INPUT                                                                 */ | 
    
    | 56 |  |  | /*                                                                        */ | 
    
    | 57 |  |  | /*    media_ptr                             Media control block pointer   */ | 
    
    | 58 |  |  | /*    file_name                             File name pointer             */ | 
    
    | 59 |  |  | /*    attributes                            New file attributes           */ | 
    
    | 60 |  |  | /*                                                                        */ | 
    
    | 61 |  |  | /*  OUTPUT                                                                */ | 
    
    | 62 |  |  | /*                                                                        */ | 
    
    | 63 |  |  | /*    return status                                                       */ | 
    
    | 64 |  |  | /*                                                                        */ | 
    
    | 65 |  |  | /*  CALLS                                                                 */ | 
    
    | 66 |  |  | /*                                                                        */ | 
    
    | 67 |  |  | /*    _fx_directory_entry_write             Write the new directory entry */ | 
    
    | 68 |  |  | /*    _fx_directory_search                  Search for the file name in   */ | 
    
    | 69 |  |  | /*                                          the directory structure       */ | 
    
    | 70 |  |  | /*    _fx_fault_tolerant_transaction_start  Start fault tolerant          */ | 
    
    | 71 |  |  | /*                                            transaction                 */ | 
    
    | 72 |  |  | /*    _fx_fault_tolerant_transaction_end    End fault tolerant transaction*/ | 
    
    | 73 |  |  | /*    _fx_fault_tolerant_recover            Recover FAT chain             */ | 
    
    | 74 |  |  | /*    _fx_fault_tolerant_reset_log_file     Reset the log file            */ | 
    
    | 75 |  |  | /*                                                                        */ | 
    
    | 76 |  |  | /*  CALLED BY                                                             */ | 
    
    | 77 |  |  | /*                                                                        */ | 
    
    | 78 |  |  | /*    Application Code                                                    */ | 
    
    | 79 |  |  | /*                                                                        */ | 
    
    | 80 |  |  | /*  RELEASE HISTORY                                                       */ | 
    
    | 81 |  |  | /*                                                                        */ | 
    
    | 82 |  |  | /*    DATE              NAME                      DESCRIPTION             */ | 
    
    | 83 |  |  | /*                                                                        */ | 
    
    | 84 |  |  | /*  05-19-2020     William E. Lamie         Initial Version 6.0           */ | 
    
    | 85 |  |  | /*  09-30-2020     William E. Lamie         Modified comment(s),          */ | 
    
    | 86 |  |  | /*                                            resulting in version 6.1    */ | 
    
    | 87 |  |  | /*                                                                        */ | 
    
    | 88 |  |  | /**************************************************************************/ | 
    
    | 89 |  | 11 | UINT  _fx_file_attributes_set(FX_MEDIA *media_ptr, CHAR *file_name, UINT attributes) | 
    
    | 90 |  |  | { | 
    
    | 91 |  |  |  | 
    
    | 92 |  |  | UINT         status; | 
    
    | 93 |  |  | ULONG        open_count; | 
    
    | 94 |  |  | FX_FILE     *search_ptr; | 
    
    | 95 |  |  | FX_DIR_ENTRY dir_entry; | 
    
    | 96 |  |  | UCHAR        not_a_file_attr; | 
    
    | 97 |  |  |  | 
    
    | 98 |  |  |  | 
    
    | 99 |  |  | #ifndef FX_MEDIA_STATISTICS_DISABLE | 
    
    | 100 |  |  |  | 
    
    | 101 |  |  |     /* Increment the number of times this service has been called.  */ | 
    
    | 102 |  | 11 |     media_ptr -> fx_media_file_attributes_sets++; | 
    
    | 103 |  |  | #endif | 
    
    | 104 |  |  |  | 
    
    | 105 |  |  |     /* Setup pointer to media name buffer.  */ | 
    
    | 106 |  | 11 |     dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN; | 
    
    | 107 |  |  |  | 
    
    | 108 |  |  |     /* Clear the short name string.  */ | 
    
    | 109 |  | 11 |     dir_entry.fx_dir_entry_short_name[0] =  0; | 
    
    | 110 |  |  |  | 
    
    | 111 |  |  |     /* Check the media to make sure it is open.  */ | 
    
    | 112 | ✓✓ | 11 |     if (media_ptr -> fx_media_id != FX_MEDIA_ID) | 
    
    | 113 |  |  |     { | 
    
    | 114 |  |  |  | 
    
    | 115 |  |  |         /* Return the media not opened error.  */ | 
    
    | 116 |  | 1 |         return(FX_MEDIA_NOT_OPEN); | 
    
    | 117 |  |  |     } | 
    
    | 118 |  |  | #ifdef FX_ENABLE_EXFAT | 
    
    | 119 |  |  |     if (media_ptr -> fx_media_FAT_type == FX_exFAT) | 
    
    | 120 |  |  |     { | 
    
    | 121 |  |  |         not_a_file_attr = FX_DIRECTORY; | 
    
    | 122 |  |  |     } | 
    
    | 123 |  |  |     else | 
    
    | 124 |  |  |     { | 
    
    | 125 |  |  | #endif /* FX_ENABLE_EXFAT */ | 
    
    | 126 |  | 10 |         not_a_file_attr = FX_DIRECTORY | FX_VOLUME; | 
    
    | 127 |  |  | #ifdef FX_ENABLE_EXFAT | 
    
    | 128 |  |  |     } | 
    
    | 129 |  |  | #endif /* FX_ENABLE_EXFAT */ | 
    
    | 130 |  |  |  | 
    
    | 131 |  |  |     /* If trace is enabled, insert this event into the trace buffer.  */ | 
    
    | 132 |  |  |     FX_TRACE_IN_LINE_INSERT(FX_TRACE_FILE_ATTRIBUTES_SET, media_ptr, file_name, attributes, 0, FX_TRACE_FILE_EVENTS, 0, 0) | 
    
    | 133 |  |  |  | 
    
    | 134 |  |  |     /* Protect against other threads accessing the media.  */ | 
    
    | 135 |  | 10 |     FX_PROTECT | 
    
    | 136 |  |  |  | 
    
    | 137 |  |  |     /* Check for write protect at the media level (set by driver).  */ | 
    
    | 138 | ✓✓ | 10 |     if (media_ptr -> fx_media_driver_write_protect) | 
    
    | 139 |  |  |     { | 
    
    | 140 |  |  |  | 
    
    | 141 |  |  |         /* Release media protection.  */ | 
    
    | 142 |  | 1 |         FX_UNPROTECT | 
    
    | 143 |  |  |  | 
    
    | 144 |  |  |         /* Return write protect error.  */ | 
    
    | 145 |  | 1 |         return(FX_WRITE_PROTECT); | 
    
    | 146 |  |  |     } | 
    
    | 147 |  |  |  | 
    
    | 148 |  |  |     /* Search the system for the supplied file name.  */ | 
    
    | 149 |  | 9 |     status =  _fx_directory_search(media_ptr, file_name, &dir_entry, FX_NULL, FX_NULL); | 
    
    | 150 |  |  |  | 
    
    | 151 |  |  |     /* Determine if the search was successful.  */ | 
    
    | 152 | ✓✓ | 9 |     if (status != FX_SUCCESS) | 
    
    | 153 |  |  |     { | 
    
    | 154 |  |  |  | 
    
    | 155 |  |  |         /* Release media protection.  */ | 
    
    | 156 |  | 2 |         FX_UNPROTECT | 
    
    | 157 |  |  |  | 
    
    | 158 |  |  |         /* Return the error code.  */ | 
    
    | 159 |  | 2 |         return(status); | 
    
    | 160 |  |  |     } | 
    
    | 161 |  |  |  | 
    
    | 162 |  |  |     /* Check to make sure the found entry is a file.  */ | 
    
    | 163 | ✓✓ | 7 |     if (dir_entry.fx_dir_entry_attributes & not_a_file_attr) | 
    
    | 164 |  |  |     { | 
    
    | 165 |  |  |  | 
    
    | 166 |  |  |         /* Release media protection.  */ | 
    
    | 167 |  | 1 |         FX_UNPROTECT | 
    
    | 168 |  |  |  | 
    
    | 169 |  |  |         /* Return the not a file error code.  */ | 
    
    | 170 |  | 1 |         return(FX_NOT_A_FILE); | 
    
    | 171 |  |  |     } | 
    
    | 172 |  |  |  | 
    
    | 173 |  |  |     /* Search the opened files to see if this file is currently | 
    
    | 174 |  |  |        opened.  */ | 
    
    | 175 |  | 6 |     open_count =  media_ptr -> fx_media_opened_file_count; | 
    
    | 176 |  | 6 |     search_ptr =  media_ptr -> fx_media_opened_file_list; | 
    
    | 177 | ✓✓ | 18 |     while (open_count) | 
    
    | 178 |  |  |     { | 
    
    | 179 |  |  |  | 
    
    | 180 |  |  |         /* Look at each opened file to see if the same file is opened.  */ | 
    
    | 181 | ✓✓ | 13 |         if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector == dir_entry.fx_dir_entry_log_sector) && | 
    
    | 182 | ✓✓ | 6 |             (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset == dir_entry.fx_dir_entry_byte_offset)) | 
    
    | 183 |  |  |         { | 
    
    | 184 |  |  |  | 
    
    | 185 |  |  |             /* Release media protection.  */ | 
    
    | 186 |  | 1 |             FX_UNPROTECT | 
    
    | 187 |  |  |  | 
    
    | 188 |  |  |             /* The file is currently open.  */ | 
    
    | 189 |  | 1 |             return(FX_ACCESS_ERROR); | 
    
    | 190 |  |  |         } | 
    
    | 191 |  |  |  | 
    
    | 192 |  |  |         /* Adjust the pointer and decrement the search count.  */ | 
    
    | 193 |  | 12 |         search_ptr =  search_ptr -> fx_file_opened_next; | 
    
    | 194 |  | 12 |         open_count--; | 
    
    | 195 |  |  |     } | 
    
    | 196 |  |  |  | 
    
    | 197 |  |  |     /* Place the new attributes in the directory entry.  */ | 
    
    | 198 |  | 5 |     dir_entry.fx_dir_entry_attributes =  (UCHAR)attributes; | 
    
    | 199 |  |  |  | 
    
    | 200 |  |  | #ifdef FX_ENABLE_FAULT_TOLERANT | 
    
    | 201 |  |  |     /* Start transaction. */ | 
    
    | 202 |  |  |     _fx_fault_tolerant_transaction_start(media_ptr); | 
    
    | 203 |  |  | #endif /* FX_ENABLE_FAULT_TOLERANT */ | 
    
    | 204 |  |  |  | 
    
    | 205 |  |  |     /* Now write out the directory entry.  */ | 
    
    | 206 |  |  | #ifdef FX_ENABLE_EXFAT | 
    
    | 207 |  |  |     if (media_ptr -> fx_media_FAT_type == FX_exFAT) | 
    
    | 208 |  |  |     { | 
    
    | 209 |  |  |         status = _fx_directory_exFAT_entry_write(media_ptr, &dir_entry, UPDATE_FILE); | 
    
    | 210 |  |  |     } | 
    
    | 211 |  |  |     else | 
    
    | 212 |  |  |     { | 
    
    | 213 |  |  | #endif /* FX_ENABLE_EXFAT */ | 
    
    | 214 |  | 5 |         status = _fx_directory_entry_write(media_ptr, &dir_entry); | 
    
    | 215 |  |  | #ifdef FX_ENABLE_EXFAT | 
    
    | 216 |  |  |     } | 
    
    | 217 |  |  | #endif /* FX_ENABLE_EXFAT */ | 
    
    | 218 |  |  |  | 
    
    | 219 |  |  | #ifdef FX_ENABLE_FAULT_TOLERANT | 
    
    | 220 |  |  |     /* Check for a bad status.  */ | 
    
    | 221 |  |  |     if (status != FX_SUCCESS) | 
    
    | 222 |  |  |     { | 
    
    | 223 |  |  |  | 
    
    | 224 |  |  |         FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | 
    
    | 225 |  |  |  | 
    
    | 226 |  |  |         /* Release media protection.  */ | 
    
    | 227 |  |  |         FX_UNPROTECT | 
    
    | 228 |  |  |  | 
    
    | 229 |  |  |         /* Return the bad status.  */ | 
    
    | 230 |  |  |         return(status); | 
    
    | 231 |  |  |     } | 
    
    | 232 |  |  |  | 
    
    | 233 |  |  |     /* End transaction. */ | 
    
    | 234 |  |  |     status = _fx_fault_tolerant_transaction_end(media_ptr); | 
    
    | 235 |  |  | #endif /* FX_ENABLE_FAULT_TOLERANT */ | 
    
    | 236 |  |  |  | 
    
    | 237 |  |  |     /* Release media protection.  */ | 
    
    | 238 |  | 5 |     FX_UNPROTECT | 
    
    | 239 |  |  |  | 
    
    | 240 |  |  |     /* File attribute set is complete, return status.  */ | 
    
    | 241 |  | 5 |     return(status); | 
    
    | 242 |  |  | } | 
    
    | 243 |  |  |  |