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