GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_directory_local_path_set.c Lines: 88 88 100.0 %
Date: 2024-01-10 21:53:23 Branches: 70 70 100.0 %

Line Branch Exec Source
1
/**************************************************************************/
2
/*                                                                        */
3
/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4
/*                                                                        */
5
/*       This software is licensed under the Microsoft Software License   */
6
/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7
/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8
/*       and in the root directory of this software.                      */
9
/*                                                                        */
10
/**************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** FileX Component                                                       */
17
/**                                                                       */
18
/**   Directory                                                           */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
#define FX_SOURCE_CODE
24
25
26
/* Include necessary system files.  */
27
28
#include "fx_api.h"
29
#include "fx_system.h"
30
#include "fx_file.h"
31
#include "fx_utility.h"
32
#include "fx_directory.h"
33
34
#ifndef FX_NO_LOCAL_PATH
35
FX_LOCAL_PATH_SETUP
36
#endif
37
38
/**************************************************************************/
39
/*                                                                        */
40
/*  FUNCTION                                               RELEASE        */
41
/*                                                                        */
42
/*    _fx_directory_local_path_set                        PORTABLE C      */
43
/*                                                           6.1.5        */
44
/*  AUTHOR                                                                */
45
/*                                                                        */
46
/*    William E. Lamie, Microsoft Corporation                             */
47
/*                                                                        */
48
/*  DESCRIPTION                                                           */
49
/*                                                                        */
50
/*    This function sets the local default directory of the media to the  */
51
/*    path specified by the caller.  If this path is not found, an error  */
52
/*    code is returned.                                                   */
53
/*                                                                        */
54
/*  INPUT                                                                 */
55
/*                                                                        */
56
/*    media_ptr                             Media control block pointer   */
57
/*    local_path                            Local path control block ptr  */
58
/*    new_path_name                         New path to set current local */
59
/*                                            working directory to        */
60
/*                                                                        */
61
/*  OUTPUT                                                                */
62
/*                                                                        */
63
/*    return status                                                       */
64
/*                                                                        */
65
/*  CALLS                                                                 */
66
/*                                                                        */
67
/*    _fx_directory_search                  Search for the directory name */
68
/*                                          in the directory structure    */
69
/*                                                                        */
70
/*  CALLED BY                                                             */
71
/*                                                                        */
72
/*    Application Code                                                    */
73
/*                                                                        */
74
/*  RELEASE HISTORY                                                       */
75
/*                                                                        */
76
/*    DATE              NAME                      DESCRIPTION             */
77
/*                                                                        */
78
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
79
/*  09-30-2020     William E. Lamie         Modified comment(s),          */
80
/*                                            resulting in version 6.1    */
81
/*  03-02-2021     William E. Lamie         Modified comment(s),          */
82
/*                                            resulting in version 6.1.5  */
83
/*                                                                        */
84
/**************************************************************************/
85
197
UINT  _fx_directory_local_path_set(FX_MEDIA *media_ptr, FX_LOCAL_PATH *local_path_ptr, CHAR *new_path_name)
86
{
87
88
#ifndef FX_NO_LOCAL_PATH
89
UINT         status;
90
CHAR        *path_string_ptr;
91
UINT         path_string_capacity;
92
FX_PATH     *path_ptr;
93
UINT         i, j;
94
#endif
95
FX_DIR_ENTRY dir_entry;
96
97
98
#ifndef FX_MEDIA_STATISTICS_DISABLE
99
100
    /* Increment the number of times this service has been called.  */
101
197
    media_ptr -> fx_media_directory_local_path_sets++;
102
#endif
103
104
    /* Setup pointer to a name buffer.  */
105
197
    dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
106
107
    /* Setup the local path name buffer pointer.  */
108
197
    local_path_ptr -> fx_path_directory.fx_dir_entry_name =  local_path_ptr -> fx_path_name_buffer;
109
110
    /* Clear the short name string.  */
111
197
    dir_entry.fx_dir_entry_short_name[0] =  (CHAR)0;
112
113
    /* Clear the long name string.  */
114
197
    dir_entry.fx_dir_entry_name[0] =  (CHAR)0;
115
116
    /* Check the media to make sure it is open.  */
117
197
    if (media_ptr -> fx_media_id != FX_MEDIA_ID)
118
    {
119
120
        /* Return the media not opened error.  */
121
1
        return(FX_MEDIA_NOT_OPEN);
122
    }
123
124
#ifdef FX_NO_LOCAL_PATH
125
126
    FX_PARAMETER_NOT_USED(new_path_name);
127
128
    /* Error, return to caller.  */
129
    return(FX_NOT_IMPLEMENTED);
130
#else
131
132
    /* If trace is enabled, insert this event into the trace buffer.  */
133
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_DIRECTORY_LOCAL_PATH_SET, media_ptr, local_path_ptr, new_path_name, 0, FX_TRACE_DIRECTORY_EVENTS, 0, 0)
134
135
    /* Protect against other threads accessing the media.  */
136
196
    FX_PROTECT
137
138
    /* Look for a root directory selection.  */
139


196
    if ((!new_path_name) || (((new_path_name[0] == '\\') || (new_path_name[0] == '/')) && (new_path_name[1] == (CHAR)0)))
140
    {
141
142
        /* Set the default local directory to the root.  */
143
5
        local_path_ptr -> fx_path_directory.fx_dir_entry_name[0] =  (CHAR)0;
144
5
        local_path_ptr -> fx_path_string[0] =                       (CHAR)0;
145
5
        local_path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] =       (CHAR)0;
146
147
        /* Setup thread control block to use this local path pointer.  */
148
5
        _tx_thread_current_ptr -> tx_thread_filex_ptr =  (VOID *)local_path_ptr;
149
    }
150
    else
151
    {
152
153
        /* Search the system for the supplied path and directory name.  */
154
191
        status =  _fx_directory_search(media_ptr, new_path_name, &dir_entry, FX_NULL, FX_NULL);
155
156
        /* Determine if the search failed or if the entry found is not a
157
           directory.  */
158

191
        if ((status != FX_SUCCESS) || (!(dir_entry.fx_dir_entry_attributes & FX_DIRECTORY)))
159
        {
160
161
            /* Release media protection.  */
162
7
            FX_UNPROTECT
163
164
            /* Invalid Path - Return the error code.  */
165
7
            return(FX_INVALID_PATH);
166
        }
167
168
        /* Now update the current path string.  */
169
170
        /* Setup the path string pointer to the start of the current path.  */
171
184
        path_string_ptr =  &(local_path_ptr -> fx_path_string[0]);
172
173
        /* Setup the path string's capacity.  */
174
184
        path_string_capacity =  FX_MAXIMUM_PATH - 1;
175
176
        /* Determine if the new path is relative from the current path.  */
177

184
        if ((new_path_name[0] != '\\') && (new_path_name[0] != '/'))
178
        {
179
180
            /* Yes, a relative path was found.  */
181
182
            /* Setup the default path pointer to the local path.  */
183
180
            path_ptr =  local_path_ptr;
184
185
            /* Determine if the local path is different than the current local path.  */
186
180
            if (local_path_ptr !=  (FX_LOCAL_PATH *)_tx_thread_current_ptr -> tx_thread_filex_ptr)
187
            {
188
189
                /* Yes, there is a difference.  */
190
191
                /* Should we copy from the default media path or from the previous default
192
                   path.  */
193
81
                if (_tx_thread_current_ptr -> tx_thread_filex_ptr)
194
                {
195
196
                    /* There is a local path so copy the relative path info from it.  */
197
70
                    i =  0;
198
                    do
199
                    {
200
201
                        /* Copy from previous local to new local path.  */
202
1573
                        local_path_ptr -> fx_path_string[i] =
203
1573
                            ((FX_LOCAL_PATH *)_tx_thread_current_ptr -> tx_thread_filex_ptr) -> fx_path_string[i];
204
205
                        /* Determine if we are done.  */
206
1573
                        if (local_path_ptr -> fx_path_string[i] == 0)
207
                        {
208
209
                            /* Are we not at the end of the string?  */
210
70
                            if (i < (FX_MAXIMUM_PATH - 1))
211
                            {
212
213
                                /* Yes, break the loop.  */
214
69
                                break;
215
                            }
216
                        }
217
218
                        /* Move to the next character.  */
219
1504
                        i++;
220
221
1504
                    } while (i < FX_MAXIMUM_PATH);
222
                }
223
                else
224
                {
225
226
                    /* No local path, so copy the relative path information from the media
227
                       default.  */
228
11
                    i =  0;
229
                    do
230
                    {
231
232
                        /* Copy from the media default to new local path.  */
233
266
                        local_path_ptr -> fx_path_string[i] =
234
266
                            media_ptr -> fx_media_default_path.fx_path_string[i];
235
236
                        /* Determine if we are done.  */
237
266
                        if (local_path_ptr -> fx_path_string[i] == 0)
238
                        {
239
240
                            /* Are we not at the end of the string?  */
241
11
                            if (i < (FX_MAXIMUM_PATH - 1))
242
                            {
243
244
                                /* Yes, break the loop.  */
245
10
                                break;
246
                            }
247
                        }
248
249
                        /* Move to the next character.  */
250
256
                        i++;
251
252
256
                    } while (i < FX_MAXIMUM_PATH);
253
                }
254
            }
255
256
            /* First, check the current path for string overflow.  If this is set,
257
               don't attempt to update the current path with relative information.
258
               The path won't be valid again until a complete path is given.  */
259
180
            if (path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] == '*')
260
            {
261
262
                /* Yes, don't update the string, just finish the path set processing.  */
263
264
                /* Determine if we are at the root directory.  */
265
47
                if (!dir_entry.fx_dir_entry_cluster)
266
                {
267
                    /* Set the current directory back to the root directory.  */
268
4
                    dir_entry.fx_dir_entry_name[0] =  (CHAR)0;
269
270
                    /* Clear the current path string.  */
271
4
                    path_ptr -> fx_path_string[0] =  (CHAR)0;
272
273
                    /* Clear the overflow flag in the current path string... just in
274
                       case! */
275
4
                    path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] =  (CHAR)0;
276
                }
277
278
                /* Copy the new directory entry into the media control block.  */
279
47
                path_ptr -> fx_path_directory =  dir_entry;
280
281
                /* Reset the local path name buffer pointer, since it was clobbered earlier.  */
282
47
                local_path_ptr -> fx_path_directory.fx_dir_entry_name =  local_path_ptr -> fx_path_name_buffer;
283
284
                /* Copy the directory name entry to the local path name area.  */
285
12079
                for (j = 0; j < FX_MAX_LONG_NAME_LEN; j++)
286
                {
287
288
                    /* Copy the name buffer.  */
289
12032
                    local_path_ptr -> fx_path_directory.fx_dir_entry_name[j] =  dir_entry.fx_dir_entry_name[j];
290
                }
291
292
                /* Setup thread control block to use this local path pointer.  */
293
47
                _tx_thread_current_ptr -> tx_thread_filex_ptr =  (VOID *)local_path_ptr;
294
295
                /* Release media protection.  */
296
47
                FX_UNPROTECT
297
298
                /* Default directory set is complete, return status.  */
299
47
                return(FX_SUCCESS);
300
            }
301
302
            /* Move the current path starting pointer to the end of the current
303
               path string.  */
304

7325
            while ((path_string_capacity) && (*path_string_ptr != FX_NULL))
305
            {
306
7192
                path_string_ptr++;
307
7192
                path_string_capacity--;
308
            }
309
310
            /* If room, place the \ character in the path string.  */
311
133
            if (path_string_capacity)
312
            {
313
314
                /* There is room, place the directory marker in the string.  */
315
132
                *path_string_ptr++ =  '\\';
316
132
                path_string_capacity--;
317
            }
318
        }
319
        else
320
        {
321
322
            /* Setup the default path pointer.  */
323
324
            /* Setup the default path pointer to the local path.  */
325
4
            path_ptr =  local_path_ptr;
326
327
            /* Complete path name given.  Check to see if we need to clear an
328
               overflow character from a previous current path string update.  */
329
4
            if (path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] == '*')
330
            {
331
1
                path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] = (CHAR)0;
332
            }
333
        }
334
335
        /* Copy what we can into the current path.  */
336
3091
        while (*new_path_name)
337
        {
338
339
            /* Determine if there is a ".." character sequence that specifies the
340
               previous path.  */
341

2959
            if ((*new_path_name == '.') && (*(new_path_name + 1) == '.'))
342
            {
343
344
                /* Yes, a backward path is found.  The current path pointer
345
                   must be moved back to just after the previous \ character.  */
346
347
                /* Skip the current \0 that is at the end of the current path.  */
348
6
                path_string_capacity =  path_string_capacity + 2;
349
6
                path_string_ptr =       path_string_ptr - 2;
350
351
109
                while (path_string_capacity <= (FX_MAXIMUM_PATH - 1))
352
                {
353
354
                    /* Move the current path pointer backwards until
355
                       a \ character is found.  */
356
357

107
                    if ((*path_string_ptr == '\\') || (*path_string_ptr == '/'))
358
                    {
359
360
                        /* Yes, we have successfully backed up one directory.  */
361
                        break;
362
                    }
363
364
                    /* Backup another character.  */
365
103
                    path_string_capacity++;
366
103
                    path_string_ptr--;
367
                }
368
369
                /* Adjust the new directory pointer past the .. characters  */
370
6
                new_path_name =  new_path_name + 2;
371
            }
372
            else
373
            {
374
375
                /* Normal characters that need to be copied into the current path.  */
376
377
2953
                if (path_string_capacity)
378
                {
379
380
                    /* Copy character from the new path into the current path string.  */
381
2948
                    *path_string_ptr++ =  *new_path_name++;
382
383
2948
                    path_string_capacity--;
384
                }
385
                else
386
                {
387
388
                    /* No more room in the current path string!  */
389
5
                    break;
390
                }
391
            }
392
        }
393
394
        /* Determine if there is still room in the current path string.  */
395
137
        if (path_string_capacity)
396
        {
397
398
            /* Yes, there is still room, place a NULL character at the
399
               end of the path.  */
400
130
            *path_string_ptr =  (CHAR)FX_NULL;
401
        }
402
        else
403
        {
404
405
            /* No more room.  Determine if the entire path was successfully
406
               copied into the current path.  */
407
7
            if (*new_path_name)
408
            {
409
410
                /* No, we couldn't fit the entire path.  Place a "*" character
411
                   at the end to indicate that we had overflow.  Note that
412
                   the path is kept just the the directory default get call, so
413
                   the new default path is valid.  */
414
5
                path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] =  '*';
415
            }
416
        }
417
418
        /* Determine if we are at the root directory.  */
419
137
        if (!dir_entry.fx_dir_entry_cluster)
420
        {
421
            /* Set the current directory back to the root directory.  */
422
3
            dir_entry.fx_dir_entry_name[0] =            (CHAR)0;
423
3
            local_path_ptr -> fx_path_name_buffer[0] =  (CHAR)0;
424
        }
425
426
        /* Copy the new directory entry into the media control block.  */
427
137
        path_ptr -> fx_path_directory =  dir_entry;
428
429
        /* Reset the local path name buffer pointer, since it was clobbered earlier.  */
430
137
        local_path_ptr -> fx_path_directory.fx_dir_entry_name =  local_path_ptr -> fx_path_name_buffer;
431
432
        /* Copy the directory name entry to the local path name area.  */
433
35209
        for (j = 0; j < FX_MAX_LONG_NAME_LEN; j++)
434
        {
435
436
            /* Copy the name buffer.  */
437
35072
            local_path_ptr -> fx_path_directory.fx_dir_entry_name[j] =  dir_entry.fx_dir_entry_name[j];
438
        }
439
440
        /* Setup thread control block to use this local path pointer.  */
441
137
        _tx_thread_current_ptr -> tx_thread_filex_ptr =  (VOID *)local_path_ptr;
442
    }
443
444
    /* Release media protection.  */
445
142
    FX_UNPROTECT
446
447
    /* Default directory set is complete, return status.  */
448
142
    return(FX_SUCCESS);
449
#endif
450
}
451