1 /* This test is determined to cover lines in fx_unicode_directory_entry_read.c.                 */
2 /* We need a dir_entry whose first byte, ordinal number byte, is big enoutgh to exceed the the  */
3 /* limit of FX_MAX_LONG_NAME_LEN, so we created a disk with a corrupt dir_entry.                */
4 #ifndef FX_STANDALONE_ENABLE
5 #include   "tx_api.h"
6 #include   "tx_thread.h"
7 #endif
8 #include   "fx_api.h"
9 #include   "fx_ram_driver_test.h"
10 #include   "fx_utility.h"
11 #include   "fx_unicode.h"
12 #include   <stdio.h>
13 
14 #define     DEMO_STACK_SIZE         8192
15 #define     CACHE_SIZE              16*128
16 
17 /* Define the ThreadX and FileX object control blocks...  */
18 
19 #ifndef FX_STANDALONE_ENABLE
20 static TX_THREAD                ftest_0;
21 #endif
22 static FX_MEDIA                 ram_disk;
23 
24 /* Define the counters used in the test application...  */
25 
26 #ifndef FX_STANDALONE_ENABLE
27 static UCHAR                    *ram_disk_memory;
28 static UCHAR                    *cache_buffer;
29 #else
30 static UCHAR                     cache_buffer[CACHE_SIZE];
31 #endif
32 
33 /* Define thread prototypes.  */
34 
35 void    filex_unicode_directory_entry_test_application_define(void *first_unused_memory);
36 static void    ftest_0_entry(ULONG thread_input);
37 
38 VOID  _fx_ram_driver(FX_MEDIA *media_ptr);
39 void  test_control_return(UINT status);
40 
41 /* Create a terrible driver. */
42 static UINT driver_called_counter = 0;
_fx_terrible_driver(FX_MEDIA * media_ptr)43 static void _fx_terrible_driver(FX_MEDIA *media_ptr)
44 {
45     driver_called_counter++;
46 //    printf("\n_fx_terrible_driver has been called %d times.", driver_called_counter);
47     if (
48         (driver_called_counter <= 3)
49         )
50     {
51         media_ptr -> fx_media_driver_status = FX_IO_ERROR;
52         return;
53     }
54 
55     (* _fx_ram_driver)(media_ptr);
56 }
57 /* Define what the initial system looks like.  */
58 
59 #ifdef CTEST
test_application_define(void * first_unused_memory)60 void test_application_define(void *first_unused_memory)
61 #else
62 void    filex_unicode_directory_entry_test_application_define(void *first_unused_memory)
63 #endif
64 {
65 
66 #ifndef FX_STANDALONE_ENABLE
67 UCHAR    *pointer;
68 
69 
70     /* Setup the working pointer.  */
71     pointer =  (UCHAR *) first_unused_memory;
72 
73     /* Create the main thread.  */
74     tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
75             pointer, DEMO_STACK_SIZE,
76             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
77 
78     pointer =  pointer + DEMO_STACK_SIZE;
79 
80     /* Setup memory for the RAM disk and the sector cache.  */
81     cache_buffer =  pointer;
82     pointer =  pointer + CACHE_SIZE;
83     ram_disk_memory =  pointer;
84 
85 #endif
86 
87     /* Initialize the FileX system.  */
88     fx_system_initialize();
89 #ifdef FX_STANDALONE_ENABLE
90     ftest_0_entry(0);
91 #endif
92 }
93 
94 /* Define the test threads.  */
95 
ftest_0_entry(ULONG thread_input)96 static void    ftest_0_entry(ULONG thread_input)
97 {
98 
99 UINT        status;
100 UCHAR       destination_name[100] = {0};
101 UCHAR       buffer[512];
102 UCHAR       long_unicode_name[] =   {2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 0, 0};
103 ULONG       length = 14;
104 ULONG       dir_num1, dir_num2;
105 FX_LOCAL_PATH local_path;
106 FX_DIR_ENTRY source_dir, destination_dir;
107 
108     FX_PARAMETER_NOT_USED(thread_input);
109 
110     /* Print out some test information banners.  */
111     printf("FileX Test:   Unicode directory entry test...........................");
112 
113 
114     /* Format the media.  This needs to be done before opening it!  */
115     status =  fx_media_format(&ram_disk,
116                             _fx_ram_driver,         // Driver entry
117                             ram_disk_memory,        // RAM disk memory pointer
118                             cache_buffer,           // Media buffer pointer
119                             CACHE_SIZE,             // Media buffer size
120                             "MY_RAM_DISK",          // Volume Name
121                             1,                      // Number of FATs
122                             32,                     // Directory Entries
123                             0,                      // Hidden sectors
124                             512,                    // Total sectors
125                             128,                    // Sector size
126                             1,                      // Sectors per cluster
127                             1,                      // Heads
128                             1);                     // Sectors per track
129 
130     /* Determine if the format had an error.  */
131     return_value_if_fail( status == FX_SUCCESS, 2);
132 
133     /* Open the ram_disk.  */
134     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
135     return_value_if_fail( status == FX_SUCCESS, 3);
136 
137     /* For coverage test in fx_directory_free_search.c.
138      387                 :       4380 :                     status = _fx_directory_entry_write(media_ptr, entry_ptr);
139      388         [ -  + ]:       4380 :                     if(status != FX_SUCCESS)
140      389                 :            :                     {
141      390                 :          0 :                         return(status);
142      391                 :            :                     }
143      */
144     _fx_directory_entry_write_error_request = 1;
145 
146     /* call fx_unicode_directory_create -call-> _fx_unicode_directory_search -call-> _fx_unicode_directory_entry_read */
147     status = fx_unicode_directory_create(&ram_disk,  long_unicode_name, length, (CHAR *) destination_name);
148     return_value_if_fail( status == FX_IO_ERROR, 3);
149 
150     /* Close the media to flush buffer. Now we have a disk with a corrupt dir_entry. */
151     status = fx_media_close(&ram_disk);
152     return_value_if_fail( status == FX_SUCCESS, 4);
153 
154 
155     /* Format the media.  This needs to be done before opening it!  */
156     status =  fx_media_format(&ram_disk,
157                             _fx_ram_driver,         // Driver entry
158                             ram_disk_memory,        // RAM disk memory pointer
159                             cache_buffer,           // Media buffer pointer
160                             CACHE_SIZE,             // Media buffer size
161                             "MY_RAM_DISK",          // Volume Name
162                             1,                      // Number of FATs
163                             32,                     // Directory Entries
164                             0,                      // Hidden sectors
165                             512,                    // Total sectors
166                             128,                    // Sector size
167                             1,                      // Sectors per cluster
168                             1,                      // Heads
169                             1);                     // Sectors per track
170 
171     /* Determine if the format had an error.  */
172     return_value_if_fail( status == FX_SUCCESS, 2);
173 
174     /* Open the ram_disk.  */
175     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
176     return_value_if_fail( status == FX_SUCCESS, 3);
177 
178     /* Disable write protect */
179     ram_disk.fx_media_driver_write_protect = FX_FALSE;
180 
181     /* call fx_unicode_directory_create -call-> _fx_unicode_directory_search -call-> _fx_unicode_directory_entry_read */
182     status = fx_unicode_directory_create(&ram_disk,  long_unicode_name, length, (CHAR *) destination_name);
183     return_value_if_fail( status == FX_SUCCESS, 3);
184 
185     /* After creating first directory on a new disk, the first dir_entry must be located at the head of the disk memory buffer. */
186     /* Modify the first byte, ordinal number byte, to make a mistake. */
187     *ram_disk.fx_media_memory_buffer |= 0x1f;
188 
189     /* Close the media to flush buffer. Now we have a disk with a corrupt dir_entry. */
190     status = fx_media_close(&ram_disk);
191     return_value_if_fail( status == FX_SUCCESS, 4);
192 
193     /* Open the media and try to create the directory again to see what happened. */
194     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
195     return_value_if_fail( status == FX_SUCCESS, 5);
196 
197 #if !defined(FX_ENABLE_FAULT_TOLERANT) && !defined(FX_DISABLE_CACHE)
198     /* Try to recreate the same directory to see what happened. */
199     status = fx_unicode_directory_create(&ram_disk,  long_unicode_name, length, (CHAR *) destination_name);
200     return_value_if_fail( status == FX_SUCCESS, 6);
201 #endif
202 
203     /* At this point the three dir_entry belongs to original directory is invalid(new dir_entry's byteoffset in memory buffer is 96 bytes). */
204 
205     /* Close the media to flush buffer. Now we have a disk with a corrupt dir_entry. */
206     status = fx_media_close(&ram_disk);
207     return_value_if_fail( status == FX_SUCCESS, 7);
208 
209     /* This time, we'll modify the second dir_entry's first byte, ordinal byte, which will make the filesystem keep reading entries until FX_FILE_CORRUPT. */
210     /* Format the media.  This needs to be done before opening it!  */
211     status =  fx_media_format(&ram_disk,
212                             _fx_ram_driver,         // Driver entry
213                             ram_disk_memory,        // RAM disk memory pointer
214                             cache_buffer,           // Media buffer pointer
215                             CACHE_SIZE,             // Media buffer size
216                             "MY_RAM_DISK",          // Volume Name
217                             1,                      // Number of FATs
218                             32,                     // Directory Entries
219                             0,                      // Hidden sectors
220                             512,                    // Total sectors
221                             128,                    // Sector size
222                             1,                      // Sectors per cluster
223                             1,                      // Heads
224                             1);                     // Sectors per track
225 
226     /* Open the ram_disk.  */
227     status +=  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
228     return_value_if_fail( status == FX_SUCCESS, 8);
229 
230     /* Disable write protect */
231     ram_disk.fx_media_driver_write_protect = FX_FALSE;
232 
233     /* call fx_unicode_directory_create -call-> _fx_unicode_directory_search -call-> _fx_unicode_directory_entry_read */
234     status = fx_unicode_directory_create(&ram_disk,  long_unicode_name, length, (CHAR *) destination_name);
235     return_value_if_fail( status == FX_SUCCESS, 9);
236 
237     /* Modify second dir_entry this time to make a mistake. */
238     ram_disk.fx_media_memory_buffer[32] |= 0x1f;
239 
240     /* Close the media to flush buffer. Now we have a disk with a corrupt dir_entry. */
241     status = fx_media_close(&ram_disk);
242     return_value_if_fail( status == FX_SUCCESS, 10);
243 
244     /* Open the media and try to create the directory again to see what happened. */
245     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
246     return_value_if_fail( status == FX_SUCCESS, 11);
247 
248 #if !defined(FX_ENABLE_FAULT_TOLERANT) && !defined(FX_DISABLE_CACHE)
249     /* Try to recreate the same directory to see what happened. */
250     status = fx_unicode_directory_create(&ram_disk,  long_unicode_name, length, (CHAR *) destination_name);
251 
252     /* Since there are no appropriate long name dir_entry behind, the filesystem will read data continously untill logic sector overflow. */
253     return_value_if_fail( status == FX_FILE_CORRUPT, 12);
254 #endif
255 
256     /* Add terrible driver to make IO mistake. */
257     status = fx_media_close(&ram_disk);
258     return_value_if_fail( status == FX_SUCCESS, 13);
259 
260     /* Format the media.  This needs to be done before opening it!  */
261     status =  fx_media_format(&ram_disk,
262                             _fx_ram_driver,         // Driver entry
263                             ram_disk_memory,        // RAM disk memory pointer
264                             cache_buffer,           // Media buffer pointer
265                             CACHE_SIZE,             // Media buffer size
266                             "MY_RAM_DISK",          // Volume Name
267                             1,                      // Number of FATs
268                             32,                     // Directory Entries
269                             0,                      // Hidden sectors
270                             512,                    // Total sectors
271                             128,                    // Sector size
272                             1,                      // Sectors per cluster
273                             1,                      // Heads
274                             1);                     // Sectors per track
275     return_value_if_fail( status == FX_SUCCESS, 14);
276 
277     /* Open the ram_disk.  */
278     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
279     return_value_if_fail( status == FX_SUCCESS, 15);
280 
281     /* Register our terrible driver. */
282     ram_disk.fx_media_driver_entry = _fx_terrible_driver;
283     status = fx_unicode_directory_create(&ram_disk,  long_unicode_name, length, (CHAR *) destination_name);
284     return_value_if_fail( status == FX_IO_ERROR, 16);
285 
286     /* Unregister our terrible driver. */
287     ram_disk.fx_media_driver_entry = _fx_ram_driver;
288 
289     status = fx_media_abort( &ram_disk);
290     return_value_if_fail( status == FX_SUCCESS, 17);
291 
292     /* Format the media.  This needs to be done before opening it!  */
293     status =  fx_media_format(&ram_disk,
294                             _fx_ram_driver,         // Driver entry
295                             ram_disk_memory,        // RAM disk memory pointer
296                             cache_buffer,           // Media buffer pointer
297                             128,             // Media buffer size
298                             "MY_RAM_DISK",          // Volume Name
299                             1,                      // Number of FATs
300                             32,                     // Directory Entries
301                             0,                      // Hidden sectors
302                             512,                    // Total sectors
303                             128,                    // Sector size
304                             1,                      // Sectors per cluster
305                             1,                      // Heads
306                             1);                     // Sectors per track
307 
308     /* Open the ram_disk.  */
309     status +=  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
310     return_value_if_fail( status == FX_SUCCESS, 18);
311 
312     /* Set local path at a sub_directory. */
313     length = fx_unicode_length_get( long_unicode_name);
314     status = fx_unicode_directory_create( &ram_disk,  long_unicode_name, length, (CHAR *)destination_name);
315 #ifndef FX_STANDALONE_ENABLE
316     status +=   fx_directory_local_path_set(&ram_disk, &local_path, (CHAR *)destination_name);
317 #else
318     status +=   fx_directory_default_set(&ram_disk, (CHAR *)destination_name);
319 #endif
320     return_value_if_fail( status == FX_SUCCESS, 19);
321 
322     /* Call _fx_unicode_directory_entry_read with uncorrect initial information. */
323     destination_dir.fx_dir_entry_name = (CHAR *)buffer;
324     source_dir.fx_dir_entry_last_search_cluster = 1;
325     source_dir.fx_dir_entry_last_search_relative_cluster = 1;
326     dir_num1 = 0;
327     status = _fx_unicode_directory_entry_read( &ram_disk, &source_dir, &dir_num1, &destination_dir, destination_name, &dir_num2);
328 
329     /* Call _fx_unicode_directory_entry_read with uncorrect initial information. */
330     source_dir.fx_dir_entry_last_search_cluster = 1;
331     source_dir.fx_dir_entry_last_search_relative_cluster = 0;
332     source_dir.fx_dir_entry_last_search_log_sector = 1;
333     source_dir.fx_dir_entry_log_sector = 0;
334     status = _fx_unicode_directory_entry_read( &ram_disk, &source_dir, &dir_num1, &destination_dir, destination_name, &dir_num2);
335 
336     /* Call _fx_unicode_directory_entry_read with uncorrect initial information. */
337     source_dir.fx_dir_entry_last_search_cluster = 1;
338     source_dir.fx_dir_entry_last_search_relative_cluster = 0;
339     source_dir.fx_dir_entry_last_search_byte_offset = 0x20;
340     source_dir.fx_dir_entry_byte_offset = 0;
341     source_dir.fx_dir_entry_last_search_log_sector = 0;
342     source_dir.fx_dir_entry_log_sector = 0;
343     status = _fx_unicode_directory_entry_read( &ram_disk, &source_dir, &dir_num1, &destination_dir, destination_name, &dir_num2);
344 
345     /* Attempt to cover the branch at Line 140 in fx_utility_FAT_map_flush.c. */
346     for (UINT i = 0; i < 128; i++)
347         ram_disk.fx_media_fat_secondary_update_map[i] = 0xff;
348     _fx_utility_FAT_map_flush( &ram_disk);
349 
350     printf("SUCCESS!\n");
351     test_control_return(0);
352 }
353