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 /**   Directory                                                           */
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_directory_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 directory.  If   */
50 /*    found, the attribute set request is valid and the directory will    */
51 /*    be modified with the new attributes.  Otherwise, if the directory   */
52 /*    is not found, the appropriate error code is returned to the caller. */
53 /*                                                                        */
54 /*  INPUT                                                                 */
55 /*                                                                        */
56 /*    media_ptr                             Media control block pointer   */
57 /*    directory_name                        Directory name pointer        */
58 /*    attributes                            New dir 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_directory_attributes_set(FX_MEDIA * media_ptr,CHAR * directory_name,UINT attributes)88 UINT  _fx_directory_attributes_set(FX_MEDIA *media_ptr, CHAR *directory_name, UINT attributes)
89 {
90 
91 UINT         status;
92 FX_DIR_ENTRY dir_entry;
93 
94 #ifndef FX_MEDIA_STATISTICS_DISABLE
95 
96     /* Increment the number of times this service has been called.  */
97     media_ptr -> fx_media_directory_attributes_sets++;
98 #endif
99 
100     /* Setup pointer to media name buffer.  */
101     dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
102 
103     /* Clear the short name string.  */
104     dir_entry.fx_dir_entry_short_name[0] =  0;
105 
106     /* Check the media to make sure it is open.  */
107     if (media_ptr -> fx_media_id != FX_MEDIA_ID)
108     {
109 
110         /* Return the media not opened error.  */
111         return(FX_MEDIA_NOT_OPEN);
112     }
113 
114     /* If trace is enabled, insert this event into the trace buffer.  */
115     FX_TRACE_IN_LINE_INSERT(FX_TRACE_DIRECTORY_ATTRIBUTES_SET, media_ptr, directory_name, attributes, 0, FX_TRACE_DIRECTORY_EVENTS, 0, 0)
116 
117     /* Protect against other threads accessing the media.  */
118     FX_PROTECT
119 
120     /* Check for write protect at the media level (set by driver).  */
121     if (media_ptr -> fx_media_driver_write_protect)
122     {
123 
124         /* Release media protection.  */
125         FX_UNPROTECT
126 
127         /* Return write protect error.  */
128         return(FX_WRITE_PROTECT);
129     }
130 
131     /* Search the system for the supplied file name.  */
132     status =  _fx_directory_search(media_ptr, directory_name, &dir_entry, FX_NULL, FX_NULL);
133 
134     /* Determine if the search was successful.  */
135     if (status != FX_SUCCESS)
136     {
137 
138         /* Release media protection.  */
139         FX_UNPROTECT
140 
141         /* Return the error code.  */
142         return(status);
143     }
144 
145     /* Check to make sure the found entry is a directory.  */
146     if ((dir_entry.fx_dir_entry_attributes & (UCHAR)(FX_DIRECTORY)) == 0)
147     {
148 
149         /* Release media protection.  */
150         FX_UNPROTECT
151 
152         /* Return the not a file error code.  */
153         return(FX_NOT_DIRECTORY);
154     }
155 
156     /* Place the new attributes in the directory entry. Make sure that the
157        directory bit of the attributes is never changed. */
158     dir_entry.fx_dir_entry_attributes =  (UCHAR)(attributes | FX_DIRECTORY);
159 
160 #ifdef FX_ENABLE_FAULT_TOLERANT
161     /* Start transaction. */
162     _fx_fault_tolerant_transaction_start(media_ptr);
163 #endif /* FX_ENABLE_FAULT_TOLERANT */
164 
165     /* Now write out the directory entry.  */
166 
167     status = _fx_directory_entry_write(media_ptr, &dir_entry);
168 
169 
170 #ifdef FX_ENABLE_FAULT_TOLERANT
171     /* Check for a bad status.  If the return status is not FX_SUCCESS, finish
172        the fault tolerant transaction without flushing the logs. */
173     if (status != FX_SUCCESS)
174     {
175         FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
176     }
177     else
178     {
179 
180         /* End transaction. */
181         status = _fx_fault_tolerant_transaction_end(media_ptr);
182     }
183 
184 #endif /* FX_ENABLE_FAULT_TOLERANT */
185 
186     /* Release media protection.  */
187     FX_UNPROTECT
188 
189     /* File attribute set is complete, return status.  */
190     return(status);
191 }
192 
193