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