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 /** Media */
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_media.h"
29 #include "fx_utility.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _fx_media_check_FAT_chain_check PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* William E. Lamie, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function walks the supplied FAT chain looking for cross links */
45 /* (FAT entries already used in another FAT chain) and abnormal FAT */
46 /* entries and invalid chain termination. */
47 /* */
48 /* INPUT */
49 /* */
50 /* media_ptr Pointer to a previously */
51 /* opened media */
52 /* starting_cluster Starting cluster of FAT chain */
53 /* last_valid_cluster Last valid cluster of chain */
54 /* total_valid_clusters Total number of valid clusters*/
55 /* logical_fat Pointer to the logical FAT */
56 /* bit map */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* error Error code */
61 /* */
62 /* CALLS */
63 /* */
64 /* _fx_utility_FAT_entry_read Read a FAT entry */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* _fx_check_media Check media function */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
75 /* 09-30-2020 William E. Lamie Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
_fx_media_check_FAT_chain_check(FX_MEDIA * media_ptr,ULONG starting_cluster,ULONG * last_valid_cluster,ULONG * total_valid_clusters,UCHAR * logical_fat)79 ULONG _fx_media_check_FAT_chain_check(FX_MEDIA *media_ptr, ULONG starting_cluster, ULONG *last_valid_cluster, ULONG *total_valid_clusters, UCHAR *logical_fat)
80 {
81
82 ULONG prev_cluster, cluster, next_clust = 0;
83 ULONG cluster_number;
84 ULONG count, error;
85 UINT status;
86
87
88 /* Initialize the error code. */
89 error = 0;
90
91 /* Setup at the first cluster. */
92 cluster = starting_cluster;
93
94 /* Initialize the previous cluster. */
95 prev_cluster = 0;
96
97 /* Initialize the count to 0. */
98 count = 0;
99
100 /* Loop to walk through the FAT chain. */
101 while ((cluster >= (ULONG)FX_FAT_ENTRY_START) &&
102 (cluster < (FX_FAT_ENTRY_START + media_ptr -> fx_media_total_clusters)))
103 {
104
105 cluster_number = cluster;
106
107
108 /* Determine if this cluster is already in the logical FAT bit map. */
109 if (logical_fat[cluster_number >> 3] & (1 << (cluster_number & 7)))
110 {
111
112 /* Yes, the cluster is already being used by another file or
113 sub-directory. */
114 error = FX_FAT_CHAIN_ERROR;
115 break;
116 }
117
118 /* Now read the contents of the cluster. */
119 status = _fx_utility_FAT_entry_read(media_ptr, cluster, &next_clust);
120
121 /* Check the return status. */
122 if (status != FX_SUCCESS)
123 {
124
125 /* Yes, the cluster is already being used by another file or
126 sub-directory. */
127 error = FX_IO_ERROR;
128 break;
129 }
130
131 /* Determine if the link is circular or the count is greater than the
132 total clusters. */
133 if ((cluster == next_clust) ||
134 (next_clust < (ULONG)FX_FAT_ENTRY_START) ||
135 ((next_clust >= (FX_FAT_ENTRY_START + media_ptr -> fx_media_total_clusters)) &&
136 (next_clust != media_ptr -> fx_media_fat_last)))
137 {
138
139 error = FX_FAT_CHAIN_ERROR;
140 break;
141 }
142
143 /* Everything is good with the chain at this point. Mark it as valid. */
144 logical_fat[cluster_number >> 3] = (UCHAR)(logical_fat[cluster_number >> 3] | (1 << (cluster_number & 7)));
145
146 /* Move the cluster variable forward. */
147 prev_cluster = cluster;
148 cluster = next_clust;
149
150 /* Increment the number of valid clusters. */
151 count++;
152 }
153
154 /* Return the last valid cluster and the total valid cluster count. */
155 *last_valid_cluster = prev_cluster;
156 *total_valid_clusters = count;
157
158 /* Return error code. */
159 return(error);
160 }
161
162