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