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 /**   Unicode                                                             */
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_unicode.h"
29 #include "fx_directory.h"
30 #include "fx_utility.h"
31 #ifdef FX_ENABLE_FAULT_TOLERANT
32 #include "fx_fault_tolerant.h"
33 #endif /* FX_ENABLE_FAULT_TOLERANT */
34 
35 
36 /**************************************************************************/
37 /*                                                                        */
38 /*  FUNCTION                                               RELEASE        */
39 /*                                                                        */
40 /*    _fx_unicode_directory_create                        PORTABLE C      */
41 /*                                                           6.1          */
42 /*  AUTHOR                                                                */
43 /*                                                                        */
44 /*    William E. Lamie, Microsoft Corporation                             */
45 /*                                                                        */
46 /*  DESCRIPTION                                                           */
47 /*                                                                        */
48 /*    This function creates the specified unicode directory.              */
49 /*                                                                        */
50 /*  INPUT                                                                 */
51 /*                                                                        */
52 /*    media_ptr                             Pointer to media              */
53 /*    source_unicode_name                   Pointer to source unicode name*/
54 /*    source_unicode_length                 Unicode name length           */
55 /*    short_name                            Designated short name         */
56 /*                                                                        */
57 /*  OUTPUT                                                                */
58 /*                                                                        */
59 /*    Completion Status                                                   */
60 /*                                                                        */
61 /*  CALLS                                                                 */
62 /*                                                                        */
63 /*    _fx_directory_search                  Search directory              */
64 /*    _fx_unicode_directory_entry_change    Change unicode file name      */
65 /*    _fx_unicode_directory_search          Search for unicode name       */
66 /*    _fx_directory_create                  Create a directory            */
67 /*    _fx_fault_tolerant_transaction_start  Start fault tolerant          */
68 /*                                            transaction                 */
69 /*    _fx_fault_tolerant_transaction_end    End fault tolerant transaction*/
70 /*    _fx_fault_tolerant_recover            Recover FAT chain             */
71 /*    _fx_fault_tolerant_reset_log_file     Reset the log file            */
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),          */
83 /*                                            resulting in version 6.1    */
84 /*                                                                        */
85 /**************************************************************************/
_fx_unicode_directory_create(FX_MEDIA * media_ptr,UCHAR * source_unicode_name,ULONG source_unicode_length,CHAR * short_name)86 UINT  _fx_unicode_directory_create(FX_MEDIA *media_ptr, UCHAR *source_unicode_name, ULONG source_unicode_length, CHAR *short_name)
87 {
88 
89 FX_DIR_ENTRY dir_entry;
90 UINT         i, status;
91 ULONG        temp_length;
92 UCHAR        destination_shortname[13];
93 
94 
95     /* Setup pointer to media name buffer.  */
96     dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
97 
98     /* Clear the short name string.  */
99     dir_entry.fx_dir_entry_short_name[0] =  FX_NULL;
100 
101     /* Set destination shortname to null.  */
102     destination_shortname[0] =  FX_NULL;
103 
104     /* Clear the return short name.  */
105     short_name[0] =  FX_NULL;
106 
107     /* Check the media to make sure it is open.  */
108     if (media_ptr -> fx_media_id != FX_MEDIA_ID)
109     {
110 
111         /* Return the media not opened error.  */
112         return(FX_MEDIA_NOT_OPEN);
113     }
114 
115 
116     /* If trace is enabled, insert this event into the trace buffer.  */
117     FX_TRACE_IN_LINE_INSERT(FX_TRACE_UNICODE_DIRECTORY_CREATE, media_ptr, source_unicode_name, source_unicode_length, short_name, FX_TRACE_DIRECTORY_EVENTS, 0, 0)
118 
119     /* Protect media.  */
120     FX_PROTECT
121 
122 #ifdef FX_ENABLE_FAULT_TOLERANT
123     /* Start transaction. */
124     _fx_fault_tolerant_transaction_start(media_ptr);
125 #endif /* FX_ENABLE_FAULT_TOLERANT */
126 
127     /* Check for write protect at the media level (set by driver).  */
128     if (media_ptr -> fx_media_driver_write_protect)
129     {
130 #ifdef FX_ENABLE_FAULT_TOLERANT
131         FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
132 #endif /* FX_ENABLE_FAULT_TOLERANT */
133 
134         /* Release media protection.  */
135         FX_UNPROTECT
136 
137         /* Return write protect error.  */
138         return(FX_WRITE_PROTECT);
139     }
140 
141     /* Setup temporary length.  */
142     temp_length =  source_unicode_length;
143 
144     /* Determine if the destination directory is already present.  */
145     status =  _fx_unicode_directory_search(media_ptr, &dir_entry, destination_shortname, sizeof(destination_shortname), source_unicode_name, &temp_length, 0);
146 
147     /* Determine if the search was successful.  */
148     if (status == FX_SUCCESS)
149     {
150 #ifdef FX_ENABLE_FAULT_TOLERANT
151         FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
152 #endif /* FX_ENABLE_FAULT_TOLERANT */
153 
154         /* Release media protection.  */
155         FX_UNPROTECT
156 
157         /* Return the error code.  */
158         return(FX_ALREADY_CREATED);
159     }
160 
161     /* Okay, at this point we need to create a new long directory name that has enough space for the
162        eventual unicode directory name.  */
163 
164     /* Copy the characters from the unicode directory name and make sure they are
165        within the ASCII range.  */
166     _fx_unicode_temp_long_file_name[0] =  'z';
167     for (i = 1; i < source_unicode_length; i++)
168     {
169 
170         /* Build temporary long file name.  */
171         _fx_unicode_temp_long_file_name[i] =  (UCHAR)((INT)'0' + (i % 9));
172     }
173     _fx_unicode_temp_long_file_name[i] =  FX_NULL;
174 
175     /* Loop to try different temp long file names... if necessary.  */
176     do
177     {
178 
179         /* Create a new directory with the temp long file name.  */
180         status =  _fx_directory_create(media_ptr, (CHAR *)_fx_unicode_temp_long_file_name);
181 
182         /* Determine if there was an error.  */
183         if (status == FX_ALREADY_CREATED)
184         {
185 
186             /* Adjust the name slightly and try again!  */
187             _fx_unicode_temp_long_file_name[0]--;
188 
189             /* Determine if it is outside the lower case boundary.  */
190             if (_fx_unicode_temp_long_file_name[0] < 0x61)
191             {
192                 break;
193             }
194         }
195     } while (status == FX_ALREADY_CREATED);
196 
197     /* Determine if there was an error.  */
198     if (status)
199     {
200 #ifdef FX_ENABLE_FAULT_TOLERANT
201         FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
202 #endif /* FX_ENABLE_FAULT_TOLERANT */
203 
204         /* Release media protection.  */
205         FX_UNPROTECT
206 
207         /* Return error.  */
208         return(status);
209     }
210 
211     /* Setup pointer to media name buffer.  */
212     dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
213 
214     /* Clear the short name string.  */
215     dir_entry.fx_dir_entry_short_name[0] =  0;
216 
217     /* Search the system for the supplied file name.  */
218     status =  _fx_directory_search(media_ptr, (CHAR *)_fx_unicode_temp_long_file_name, &dir_entry, FX_NULL, FX_NULL);
219 
220     /* Determine if the search was successful.  */
221     if (status != FX_SUCCESS)
222     {
223 #ifdef FX_ENABLE_FAULT_TOLERANT
224         FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
225 #endif /* FX_ENABLE_FAULT_TOLERANT */
226 
227         /* Release media protection.  */
228         FX_UNPROTECT
229 
230         /* Return the error status.  */
231         return(status);
232     }
233 
234     /* We can now change the temporary long file name with the destination unicode name.  */
235     status =  _fx_unicode_directory_entry_change(media_ptr, &dir_entry,  source_unicode_name, source_unicode_length);
236 
237     /* Was this successful?  */
238     if (status == FX_SUCCESS)
239     {
240 
241         /* Yes, copy the short file name to the destination.  */
242         /* The new short name only have 8 characters, since we didn't include a dot in temp_long_file_name. */
243         for (i = 0; i < FX_DIR_NAME_SIZE; i++)
244         {
245 
246             /* Copy a character.  */
247             short_name[i] =  dir_entry.fx_dir_entry_short_name[i];
248 
249             /* Are we done?  */
250             if (short_name[i] == FX_NULL)
251             {
252                 break;
253             }
254         }
255     }
256 
257 #ifdef FX_ENABLE_FAULT_TOLERANT
258     /* Check for a bad status.  */
259     if (status != FX_SUCCESS)
260     {
261 
262         FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
263 
264         /* Release media protection.  */
265         FX_UNPROTECT
266 
267         /* Return the bad status.  */
268         return(status);
269     }
270 
271     /* End transaction. */
272     status = _fx_fault_tolerant_transaction_end(media_ptr);
273 #endif /* FX_ENABLE_FAULT_TOLERANT */
274 
275     /* Release the protection.  */
276     FX_UNPROTECT
277 
278     /* Return completion status.  */
279     return(status);
280 }
281 
282