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 
33 
34 /**************************************************************************/
35 /*                                                                        */
36 /*  FUNCTION                                               RELEASE        */
37 /*                                                                        */
38 /*    _fx_directory_information_get                       PORTABLE C      */
39 /*                                                           6.1          */
40 /*  AUTHOR                                                                */
41 /*                                                                        */
42 /*    William E. Lamie, Microsoft Corporation                             */
43 /*                                                                        */
44 /*  DESCRIPTION                                                           */
45 /*                                                                        */
46 /*    This function first attempts to find the specified directory name.  */
47 /*    If found, the complete file parameters are placed in all non-NULL   */
48 /*    return parameters.  If the file name is not found, the appropriate  */
49 /*    error code is returned to the caller.                               */
50 /*                                                                        */
51 /*  INPUT                                                                 */
52 /*                                                                        */
53 /*    media_ptr                             Media control block pointer   */
54 /*    directory_name                        Directory name pointer        */
55 /*    attributes                            Pointer to attributes         */
56 /*    size                                  Pointer to size               */
57 /*    year                                  Pointer to year               */
58 /*    month                                 Pointer to month              */
59 /*    day                                   Pointer to day                */
60 /*    hour                                  Pointer to hour               */
61 /*    minute                                Pointer to minute             */
62 /*    second                                Pointer to second             */
63 /*                                                                        */
64 /*  OUTPUT                                                                */
65 /*                                                                        */
66 /*    return status                                                       */
67 /*                                                                        */
68 /*  CALLS                                                                 */
69 /*                                                                        */
70 /*    _fx_directory_search                  Search for the file name in   */
71 /*                                          the directory structure       */
72 /*                                                                        */
73 /*  CALLED BY                                                             */
74 /*                                                                        */
75 /*    Application Code                                                    */
76 /*                                                                        */
77 /*  RELEASE HISTORY                                                       */
78 /*                                                                        */
79 /*    DATE              NAME                      DESCRIPTION             */
80 /*                                                                        */
81 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
82 /*  09-30-2020     William E. Lamie         Modified comment(s), verified */
83 /*                                            memcpy usage,               */
84 /*                                            resulting in version 6.1    */
85 /*                                                                        */
86 /**************************************************************************/
_fx_directory_information_get(FX_MEDIA * media_ptr,CHAR * directory_name,UINT * attributes,ULONG * size,UINT * year,UINT * month,UINT * day,UINT * hour,UINT * minute,UINT * second)87 UINT  _fx_directory_information_get(FX_MEDIA *media_ptr, CHAR *directory_name,
88                                     UINT *attributes, ULONG *size,
89                                     UINT *year, UINT *month, UINT *day,
90                                     UINT *hour, UINT *minute, UINT *second)
91 {
92 
93 UINT         status;
94 FX_DIR_ENTRY dir_entry;
95 ULONG        open_count;
96 FX_FILE     *search_ptr;
97 
98 
99 #ifndef FX_MEDIA_STATISTICS_DISABLE
100 
101     /* Increment the number of times this service has been called.  */
102     media_ptr -> fx_media_directory_information_gets++;
103 #endif
104 
105     /* Setup pointer to media name buffer.  */
106     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     dir_entry.fx_dir_entry_short_name[0] =  0;
110 
111     /* Check the media to make sure it is open.  */
112     if (media_ptr -> fx_media_id != FX_MEDIA_ID)
113     {
114 
115         /* Return the media not opened error.  */
116         return(FX_MEDIA_NOT_OPEN);
117     }
118 
119     /* If trace is enabled, insert this event into the trace buffer.  */
120     FX_TRACE_IN_LINE_INSERT(FX_TRACE_DIRECTORY_INFORMATION_GET, media_ptr, directory_name, 0, 0, FX_TRACE_DIRECTORY_EVENTS, 0, 0)
121 
122     /* Protect against other threads accessing the media.  */
123     FX_PROTECT
124 
125     /* Search the system for the supplied directory name.  */
126     status =  _fx_directory_search(media_ptr, directory_name, &dir_entry, FX_NULL, FX_NULL);
127 
128     /* Determine if the search was successful.  */
129     if (status != FX_SUCCESS)
130     {
131 
132         /* Release media protection.  */
133         FX_UNPROTECT
134 
135         /* Return the error code.  */
136         return(status);
137     }
138 
139     /* Check the list of open files for others open for writing.  */
140     open_count =  media_ptr -> fx_media_opened_file_count;
141     search_ptr =  media_ptr -> fx_media_opened_file_list;
142     while (open_count)
143     {
144 
145         /* Look at each opened file to see if the same file is opened
146            for writing.  */
147         if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector == dir_entry.fx_dir_entry_log_sector) &&
148             (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset == dir_entry.fx_dir_entry_byte_offset) &&
149             (search_ptr -> fx_file_open_mode))
150         {
151 
152             /* The file has been opened for writing by a previous call. Use the information used by
153                the writer instead of what is currently on the media.  */
154             _fx_utility_memory_copy((UCHAR *)&search_ptr -> fx_file_dir_entry, (UCHAR *)&dir_entry, sizeof(FX_DIR_ENTRY)); /* Use case of memcpy is verified. */
155             break;
156         }
157 
158         /* Adjust the pointer and decrement the search count.  */
159         search_ptr =  search_ptr -> fx_file_opened_next;
160         open_count--;
161     }
162 
163     /* Check to see if attributes are required.  */
164     if (attributes)
165     {
166 
167         /* Pickup the attributes.  */
168         *attributes =  dir_entry.fx_dir_entry_attributes;
169     }
170 
171     /* Check to see if the size is required.  */
172     if (size)
173     {
174 
175         /* Pickup the size.  */
176         *size =  (ULONG)dir_entry.fx_dir_entry_file_size;
177     }
178 
179     /* Check to see if the year is required.  */
180     if (year)
181     {
182 
183         /* Pickup the year.  */
184         *year =  ((dir_entry.fx_dir_entry_date >> FX_YEAR_SHIFT) & FX_YEAR_MASK) +
185                                                                         FX_BASE_YEAR;
186     }
187 
188     /* Check to see if the month is required.  */
189     if (month)
190     {
191 
192         /* Pickup the month.  */
193         *month =  (dir_entry.fx_dir_entry_date >> FX_MONTH_SHIFT) & FX_MONTH_MASK;
194     }
195 
196     /* Check to see if the day is required.  */
197     if (day)
198     {
199 
200         /* Pickup the day.  */
201         *day =  dir_entry.fx_dir_entry_date & FX_DAY_MASK;
202     }
203 
204     /* Check to see if the hour is required.  */
205     if (hour)
206     {
207 
208         /* Pickup the hour.  */
209         *hour =  (dir_entry.fx_dir_entry_time >> FX_HOUR_SHIFT) & FX_HOUR_MASK;
210     }
211 
212     /* Check to see if the minute is required.  */
213     if (minute)
214     {
215 
216         /* Pickup the minute.  */
217         *minute =  (dir_entry.fx_dir_entry_time >> FX_MINUTE_SHIFT) & FX_MINUTE_MASK;
218     }
219 
220     /* Check to see if the second is required.  */
221     if (second)
222     {
223 
224         /* Pickup the second.  */
225         *second =  (dir_entry.fx_dir_entry_time & FX_SECOND_MASK) * 2;
226     }
227 
228     /* Release media protection.  */
229     FX_UNPROTECT
230 
231     /* Directory information get is complete, return successful status.  */
232     return(FX_SUCCESS);
233 }
234 
235