1 /* This FileX test concentrates on the file allocate/truncate operation.  */
2 
3 #ifndef FX_STANDALONE_ENABLE
4 #include   "tx_api.h"
5 #endif
6 #include   "fx_api.h"
7 #include   <stdio.h>
8 #include   "fx_ram_driver_test.h"
9 
10 #define     DEMO_STACK_SIZE         4096
11 #define     CACHE_SIZE              128*128
12 
13 /* Define the ThreadX and FileX object control blocks...  */
14 
15 #ifndef FX_STANDALONE_ENABLE
16 static TX_THREAD               ftest_0;
17 #endif
18 static FX_MEDIA                ram_disk;
19 static FX_FILE                 my_file;
20 static FX_FILE                 my_file1;
21 static FX_FILE                 my_file2;
22 static FX_FILE                 read_only;
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 
34 /* Define thread prototypes.  */
35 
36 void    filex_file_allocate_truncate_application_define(void *first_unused_memory);
37 static void    ftest_0_entry(ULONG thread_input);
38 
39 VOID  _fx_ram_driver(FX_MEDIA *media_ptr);
40 void  test_control_return(UINT status);
41 
42 
43 
44 /* Define what the initial system looks like.  */
45 
46 #ifdef CTEST
test_application_define(void * first_unused_memory)47 void test_application_define(void *first_unused_memory)
48 #else
49 void    filex_file_allocate_truncate_application_define(void *first_unused_memory)
50 #endif
51 {
52 
53 #ifndef FX_STANDALONE_ENABLE
54 UCHAR    *pointer;
55 
56 
57     /* Setup the working pointer.  */
58     pointer =  (UCHAR *) first_unused_memory;
59 
60     /* Create the main thread.  */
61     tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
62             pointer, DEMO_STACK_SIZE,
63             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
64 
65     pointer =  pointer + DEMO_STACK_SIZE;
66 
67     /* Setup memory for the RAM disk and the sector cache.  */
68     cache_buffer =  pointer;
69     pointer =  pointer + CACHE_SIZE;
70     ram_disk_memory =  pointer;
71 
72 #endif
73 
74     /* Initialize the FileX system.  */
75     fx_system_initialize();
76 #ifdef FX_STANDALONE_ENABLE
77     ftest_0_entry(0);
78 #endif
79 }
80 
81 
82 
83 /* Define the test threads.  */
84 
ftest_0_entry(ULONG thread_input)85 static void    ftest_0_entry(ULONG thread_input)
86 {
87 
88 UINT        status;
89 ULONG       actual;
90 ULONG       temp;
91 ULONG       write_value;
92 ULONG       available_bytes;
93 CHAR        buffer[1];
94 ULONG       i;
95 
96     FX_PARAMETER_NOT_USED(thread_input);
97 
98     /* Print out some test information banners.  */
99     printf("FileX Test:   File allocate/truncate test............................");
100 
101     /* Format the media.  This needs to be done before opening it!  */
102     status =  fx_media_format(&ram_disk,
103                             _fx_ram_driver,         // Driver entry
104                             ram_disk_memory,        // RAM disk memory pointer
105                             cache_buffer,           // Media buffer pointer
106                             CACHE_SIZE,             // Media buffer size
107                             "MY_RAM_DISK",          // Volume Name
108                             1,                      // Number of FATs
109                             32,                     // Directory Entries
110                             0,                      // Hidden sectors
111                             512,                    // Total sectors
112                             128,                    // Sector size
113                             1,                      // Sectors per cluster
114                             1,                      // Heads
115                             1);                     // Sectors per track
116 
117     /* Determine if the format had an error.  */
118     if (status)
119     {
120 
121         printf("ERROR!\n");
122         test_control_return(1);
123     }
124 
125     /* Attempt to truncate a file before the file is opened */
126     status = fx_file_extended_truncate(&my_file, 0);
127     if (status != FX_NOT_OPEN)
128     {
129         printf("ERROR!\n");
130         test_control_return(2);
131     }
132 
133     /* Attempt to release a file before the file is opened */
134     status = fx_file_extended_truncate_release(&my_file, 0);
135     if (status != FX_NOT_OPEN)
136     {
137         printf("ERROR!\n");
138         test_control_return(3);
139     }
140 
141     /* Open the ram_disk.  */
142     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
143 
144     /* Check the status.  */
145     if (status != FX_SUCCESS)
146     {
147 
148         /* Error, return error code.  */
149         printf("ERROR!\n");
150         test_control_return(4);
151     }
152 
153     /* Create a file called TEST.TXT in the root directory.  */
154     status =  fx_file_create(&ram_disk, "TEST.TXT");
155 
156     /* Check the create status.  */
157     if (status != FX_SUCCESS)
158     {
159 
160         printf("ERROR!\n");
161         test_control_return(5);
162     }
163 
164     /* Create a file called READ_ONLY.TXT in the root directory.  */
165     status =  fx_file_create(&ram_disk, "READ_ONLY.TXT");
166 
167     /* Check the create status.  */
168     if (status != FX_SUCCESS)
169     {
170 
171         printf("ERROR!\n");
172         test_control_return(6);
173     }
174 
175     /* Pickup the available bytes in the media.  */
176     status =  fx_media_space_available(&ram_disk, &available_bytes);
177 
178     /* Check for available bytes error.  */
179     if ((status != FX_SUCCESS) || (available_bytes < sizeof(ULONG)))
180     {
181 
182         printf("ERROR!\n");
183         test_control_return(7);
184     }
185 
186     /* Open the test files.  */
187     status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
188     status =  fx_file_open(&ram_disk, &read_only, "READ_ONLY.TXT", FX_OPEN_FOR_READ);
189 
190     /* Check the file open status.  */
191     if (status != FX_SUCCESS)
192     {
193 
194         printf("ERROR!\n");
195         test_control_return(8);
196     }
197 
198     /* Try to release more than was allocated */
199     status = fx_file_extended_truncate_release(&my_file, 0xFFFFFFFFFFFFFFFF);
200     if (status != FX_SUCCESS)
201     {
202         printf("ERROR!\n");
203         test_control_return(9);
204     }
205 
206     /* Attempt to truncate a file that is not open for writing */
207     status = fx_file_extended_truncate(&read_only, 0);
208     if (status != FX_ACCESS_ERROR)
209     {
210         printf("ERROR!\n");
211         test_control_return(10);
212     }
213 
214     /* Attempt to release a file that is not open for writing */
215     status = fx_file_extended_truncate_release(&read_only, 0);
216     if (status != FX_ACCESS_ERROR)
217     {
218         printf("ERROR!\n");
219         test_control_return(11);
220     }
221 
222     /* Attempt to truncate a file while the media is write protected */
223     ram_disk.fx_media_driver_write_protect = FX_TRUE;
224     status = fx_file_extended_truncate(&my_file, 0);
225     if (status != FX_WRITE_PROTECT)
226     {
227         printf("ERROR!\n");
228         test_control_return(12);
229     }
230 
231     /* Attempt to release a file while the media is write protected */
232     status = fx_file_extended_truncate_release(&my_file, 0);
233     if (status != FX_WRITE_PROTECT)
234     {
235         printf("ERROR!\n");
236         test_control_return(13);
237     }
238     ram_disk.fx_media_driver_write_protect = FX_FALSE;
239 
240     ram_disk.fx_media_bytes_per_sector = 0;
241 
242     /* Attempt to release a file while the media is corrupted.  */
243     status = fx_file_extended_truncate_release(&my_file, 0);
244     if (status != FX_MEDIA_INVALID)
245     {
246         printf("ERROR!\n");
247         test_control_return(13);
248     }
249     ram_disk.fx_media_bytes_per_sector = 128;
250 
251     /* Attempt to truncate a file to larger than it is */
252     status = fx_file_extended_truncate(&my_file, 0xFFFFFFFFFFFFFFFF);
253     if (status != FX_SUCCESS)
254     {
255         printf("ERROR!\n");
256         test_control_return(14);
257     }
258 
259 /* Only run this if error checking is enabled */
260 #ifndef FX_DISABLE_ERROR_CHECKING
261     /* send null pointer to generate an error */
262     status = fx_file_allocate(FX_NULL, 1500);
263     if (status != FX_PTR_ERROR)
264     {
265         printf("ERROR!\n");
266         test_control_return(15);
267     }
268 
269     /* send null pointer to generate an error */
270     status = fx_file_extended_truncate(FX_NULL, 0xFF);
271     if (status != FX_PTR_ERROR)
272     {
273         printf("ERROR!\n");
274         test_control_return(16);
275     }
276 
277     /* send null pointer to generate an error */
278     status = fx_file_extended_truncate_release(FX_NULL, 0xFF);
279     if (status != FX_PTR_ERROR)
280     {
281         printf("ERROR!\n");
282         test_control_return(17);
283     }
284 
285     /* send null pointer to generate an error */
286     status = fx_file_extended_allocate(FX_NULL, 0xFF);
287     if (status != FX_PTR_ERROR)
288     {
289         printf("ERROR!\n");
290         test_control_return(18);
291     }
292 
293     /* send null pointer to generate an error */
294     status = fx_file_best_effort_allocate(FX_NULL, 0xFF, FX_NULL);
295     if (status != FX_PTR_ERROR)
296     {
297         printf("ERROR!\n");
298         test_control_return(19);
299     }
300 #endif /* FX_DISABLE_ERROR_CHECKING */
301 
302     /* Allocate half the size first...  */
303     status =  fx_file_allocate(&my_file, available_bytes/2);
304 
305     /* Check the file allocate status.  */
306     if (status != FX_SUCCESS)
307     {
308 
309         printf("ERROR!\n");
310         test_control_return(20);
311     }
312 
313     /* Pickup the available bytes in the media again.  */
314     status =  fx_media_space_available(&ram_disk, &i);
315 
316 
317     /* Attempt to allocate all the bytes again... but the best effort should just get us the
318        remaining bytes...  */
319     status +=  fx_file_best_effort_allocate(&my_file, available_bytes, &actual);
320 
321     /* Check the best effort file allocate status.  */
322     if ((status != FX_SUCCESS) || (actual != i))
323     {
324 
325         printf("ERROR!\n");
326         test_control_return(21);
327     }
328 
329 #ifdef FX_UPDATE_FILE_SIZE_ON_ALLOCATE
330     /* Seek to the beginning of the test file.  */
331     status =  fx_file_seek(&my_file, 0);
332 
333     /* Check the file seek status.  */
334     if (status != FX_SUCCESS)
335     {
336 
337         printf("ERROR!\n");
338         test_control_return(22);
339     }
340 
341     /* send null pointer to generate an error */
342     status = fx_file_best_effort_allocate(FX_NULL, 1500, FX_NULL);
343     if (status != FX_PTR_ERROR)
344     {
345         printf("ERROR!\n");
346         test_control_return(23);
347     }
348 #endif /* FX_DISABLE_ERROR_CHECKING */
349 
350     /* Loop to write successive bytes out to the file.... to fill the media!  */
351     i =  0;
352     write_value =  0;
353     while (i < available_bytes)
354     {
355 
356         /* Write 4 bytes to the file.  */
357         status =  fx_file_write(&my_file, (void *) &write_value, sizeof(ULONG));
358 
359         /* Check the file write status.  */
360         if (status != FX_SUCCESS)
361         {
362 
363             printf("ERROR!\n");
364             test_control_return(24);
365         }
366 
367         /* Increment byte count.  */
368         i =  i + sizeof(ULONG);
369 
370         /* Increment write value.  */
371         write_value++;
372     }
373 
374     /* Pickup the available bytes in the media again.  */
375     status =  fx_media_space_available(&ram_disk, &i);
376 
377     /* Check for available bytes error.  */
378     if ((status != FX_SUCCESS) || (i != 0))
379     {
380 
381         printf("ERROR!\n");
382         test_control_return(25);
383     }
384 
385 #ifndef FX_DISABLE_CACHE
386     /* At this point, we should invalidate the (which also flushes the cache) media to ensure that all
387        dirty sectors are written.  */
388     status =  fx_media_cache_invalidate(&ram_disk);
389 
390     /* Check for invalidate errors.  */
391     if ((status != FX_SUCCESS) || (ram_disk.fx_media_sector_cache_dirty_count))
392     {
393 
394         printf("ERROR!\n");
395         test_control_return(26);
396     }
397 
398     /* See if any sectors are still valid in the cache.  */
399     for (i = 0; i < FX_MAX_SECTOR_CACHE; i++)
400     {
401 
402         /* Determine if this cache entry is still valid.  */
403         if (ram_disk.fx_media_sector_cache[i].fx_cached_sector_valid)
404         {
405 
406             printf("ERROR!\n");
407             test_control_return(27);
408         }
409     }
410 #endif
411 
412     /* Now truncate half the file...  */
413     status =  fx_file_truncate(&my_file, available_bytes/2);
414 
415     /* Check for errors... */
416     if ((status) || (my_file.fx_file_current_file_size != my_file.fx_file_current_available_size/2))
417     {
418 
419         printf("ERROR!\n");
420         test_control_return(28);
421     }
422 
423 /* Only run this if error checking is enabled */
424 #ifndef FX_DISABLE_ERROR_CHECKING
425     /* send null pointer to generate an error */
426     status = fx_file_truncate(FX_NULL, 0);
427     if (status != FX_PTR_ERROR)
428     {
429         printf("ERROR!\n");
430         test_control_return(29);
431     }
432 
433     /* send null pointer to generate an error */
434     status = fx_file_truncate_release(FX_NULL, 0);
435     if (status != FX_PTR_ERROR)
436     {
437         printf("ERROR!\n");
438         test_control_return(30);
439     }
440 #endif /* FX_DISABLE_ERROR_CHECKING */
441 
442     /* Now truncate the remainder of file...  */
443     status =  fx_file_truncate(&my_file, 0);
444 
445     /* Check for errors... */
446     if ((status) || (my_file.fx_file_current_file_size != 0))
447     {
448 
449         printf("ERROR!\n");
450         test_control_return(31);
451     }
452 
453     /* Pickup the available bytes in the media again.  */
454     status =  fx_media_space_available(&ram_disk, &i);
455 
456     /* Check for available bytes error.  */
457     if ((status != FX_SUCCESS) || (i != 0))
458     {
459 
460         printf("ERROR!\n");
461         test_control_return(32);
462     }
463 
464     /* At this point write the file again... */
465     i =  0;
466     write_value =  0;
467     while (i < available_bytes)
468     {
469 
470         /* Write 4 bytes to the file.  */
471         status =  fx_file_write(&my_file, (void *) &write_value, sizeof(ULONG));
472 
473         /* Check the file write status.  */
474         if (status != FX_SUCCESS)
475         {
476 
477             printf("ERROR!\n");
478             test_control_return(33);
479         }
480 
481         /* Increment byte count.  */
482         i =  i + sizeof(ULONG);
483 
484         /* Increment write value.  */
485         write_value++;
486     }
487 
488     /* Now truncate and release half the file...  */
489     status =  fx_file_truncate_release(&my_file, available_bytes/2);
490 
491     /* Pickup the available bytes in the media again.  */
492     status +=  fx_media_space_available(&ram_disk, &i);
493 
494     /* Check for errors... */
495     if ((status) || (my_file.fx_file_current_file_size != available_bytes/2))
496     {
497 
498         printf("ERROR!\n");
499         test_control_return(34);
500     }
501 
502     /* Now truncate and release the remaining half the file...  */
503     status =  fx_file_truncate_release(&my_file, 0);
504 
505     /* Pickup the available bytes in the media again.  */
506     status +=  fx_media_space_available(&ram_disk, &i);
507 
508     /* Check for errors... */
509     if ((status) || (my_file.fx_file_current_file_size != 0) ||
510             (i != available_bytes))
511     {
512 
513         printf("ERROR!\n");
514         test_control_return(35);
515     }
516 
517     /* Test overflow of available bytes >4GB of this API.  */
518 
519     /* Set the available clusters to maximum value.  */
520     temp =  ram_disk.fx_media_available_clusters;
521     ram_disk.fx_media_available_clusters =  0xFFFFFFFF;
522 
523     /* Pickup the available bytes in the media again.  */
524     status =  fx_media_space_available(&ram_disk, &available_bytes);
525 
526     /* Restore the actual available clusters.  */
527     ram_disk.fx_media_available_clusters =  temp;
528 
529     /* Check for errors... */
530     if ((status) || (available_bytes != 0xFFFFFFFF))
531     {
532 
533         printf("ERROR!\n");
534         test_control_return(36);
535     }
536 
537     /* Close the file.  */
538     status =  fx_file_close(&my_file);
539 
540     /* Close the media.  */
541     status +=  fx_media_close(&ram_disk);
542 
543     /* Determine if the test was successful.  */
544     if (status != FX_SUCCESS)
545     {
546 
547         printf("ERROR!\n");
548         test_control_return(37);
549     }
550 
551 
552     /* Format the media.  This needs to be done before opening it!  */
553     status =  fx_media_format(&ram_disk,
554                             _fx_ram_driver,         // Driver entry
555                             ram_disk_memory,        // RAM disk memory pointer
556                             cache_buffer,           // Media buffer pointer
557                             CACHE_SIZE,             // Media buffer size
558                             "MY_RAM_DISK",          // Volume Name
559                             1,                      // Number of FATs
560                             32,                     // Directory Entries
561                             0,                      // Hidden sectors
562                             18000,                  // Total sectors
563                             128,                    // Sector size
564                             3,                      // Sectors per cluster
565                             1,                      // Heads
566                             1);                     // Sectors per track
567 
568     /* Determine if the format had an error.  */
569     if (status)
570     {
571 
572         printf("ERROR!\n");
573         test_control_return(38);
574     }
575 
576     /* Open the ram_disk.  */
577     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
578 
579     /* Check the status.  */
580     if (status != FX_SUCCESS)
581     {
582 
583         /* Error, return error code.  */
584         printf("ERROR!\n");
585         test_control_return(39);
586     }
587 
588     /* Create a file called TEST.TXT in the root directory.  */
589     status =  fx_file_create(&ram_disk, "TEST.TXT");
590     status += fx_file_create(&ram_disk, "TEST1.TXT");
591     status += fx_file_create(&ram_disk, "TEST2.TXT");
592     status += fx_file_create(&ram_disk, "TEST3.TXT");
593     status += fx_file_create(&ram_disk, "TEST4.TXT");
594     status += fx_file_create(&ram_disk, "TEST5.TXT");
595     status += fx_file_create(&ram_disk, "TEST6.TXT");
596     status += fx_file_create(&ram_disk, "TEST7.TXT");
597     status += fx_file_create(&ram_disk, "TEST8.TXT");
598     status += fx_file_create(&ram_disk, "TEST9.TXT");
599     status += fx_file_create(&ram_disk, "TEST10.TXT");
600     status += fx_file_create(&ram_disk, "TEST11.TXT");
601     status += fx_file_create(&ram_disk, "TEST12.TXT");
602     status += fx_file_create(&ram_disk, "TEST13.TXT");
603     status += fx_file_create(&ram_disk, "TEST14.TXT");
604     status += fx_file_create(&ram_disk, "TEST15.TXT");
605     status += fx_file_create(&ram_disk, "TEST16.TXT");
606     status += fx_file_create(&ram_disk, "TEST17.TXT");
607 
608     /* Check the create status.  */
609     if (status != FX_SUCCESS)
610     {
611 
612         printf("ERROR!\n");
613         test_control_return(40);
614     }
615 
616     /* Open the test file.  */
617     status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
618     status += fx_file_open(&ram_disk, &read_only, "TEST.TXT", FX_OPEN_FOR_READ);
619     status += fx_file_open(&ram_disk, &my_file1, "TEST1.TXT", FX_OPEN_FOR_READ);
620     status += fx_file_open(&ram_disk, &my_file2, "TEST17.TXT", FX_OPEN_FOR_READ);
621 
622     /* Write 2048 bytes to the file.  */
623     for (i = 0; i < 4096; i++)
624     {
625         /* Write a byte to the file.  */
626         status += fx_file_write(&my_file, " ", 1);
627         status += fx_file_read(&read_only, buffer, 1, &actual);
628     }
629 
630     /* Allocate some additional clusters.  */
631     status +=  fx_file_allocate(&my_file, 128*6);
632 
633     /* Check the status.  */
634     if (status != FX_SUCCESS)
635     {
636 
637         printf("ERROR!\n");
638         test_control_return(41);
639     }
640 
641     /* Now truncate the file to a value less than the available size, but greater than the current size.  */
642     status = fx_file_extended_truncate_release(&my_file, 4096 + 128);
643     if (status != FX_SUCCESS)
644     {
645         printf("ERROR!\n");
646         test_control_return(42);
647     }
648 
649     /* Now truncate the file to the available size.  */
650     status = fx_file_extended_truncate_release(&my_file, 4096);
651     if (status != FX_SUCCESS)
652     {
653         printf("ERROR!\n");
654         test_control_return(43);
655     }
656 
657     /* Now truncate the file to half the available size.  */
658     status = fx_file_extended_truncate_release(&my_file, 2048);
659     if (status != FX_SUCCESS)
660     {
661         printf("ERROR!\n");
662         test_control_return(44);
663     }
664 
665     /* Now truncate the file to nothing.  */
666     status = fx_file_extended_truncate_release(&my_file, 0);
667     if (status != FX_SUCCESS)
668     {
669         printf("ERROR!\n");
670         test_control_return(45);
671     }
672 
673     /* Close everything down.  */
674     status =  fx_file_close(&my_file);
675     status += fx_file_close(&my_file1);
676     status += fx_file_close(&my_file2);
677     status += fx_file_close(&read_only);
678     status += fx_media_close(&ram_disk);
679 
680     /* Check status.  */
681     if (status != FX_SUCCESS)
682     {
683         printf("ERROR!\n");
684         test_control_return(46);
685     }
686 
687     /* Format the media.  This needs to be done before opening it!  */
688     status =  fx_media_format(&ram_disk,
689                             _fx_ram_driver,         // Driver entry
690                             ram_disk_memory,        // RAM disk memory pointer
691                             cache_buffer,           // Media buffer pointer
692                             CACHE_SIZE,             // Media buffer size
693                             "MY_RAM_DISK",          // Volume Name
694                             1,                      // Number of FATs
695                             32,                     // Directory Entries
696                             0,                      // Hidden sectors
697                             18000,                  // Total sectors
698                             128,                    // Sector size
699                             3,                      // Sectors per cluster
700                             1,                      // Heads
701                             1);                     // Sectors per track
702 
703     /* Determine if the format had an error.  */
704     if (status)
705     {
706 
707         printf("ERROR!\n");
708         test_control_return(47);
709     }
710 
711     /* Open the ram_disk.  */
712     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, 128);
713 
714     /* Check the status.  */
715     if (status != FX_SUCCESS)
716     {
717 
718         /* Error, return error code.  */
719         printf("ERROR!\n");
720         test_control_return(48);
721     }
722 
723     /* Create a file called TEST.TXT in the root directory.  */
724     status =  fx_file_create(&ram_disk, "TEST.TXT");
725 
726     /* Check the create status.  */
727     if (status != FX_SUCCESS)
728     {
729 
730         printf("ERROR!\n");
731         test_control_return(49);
732     }
733 
734     /* Open the test file.  */
735     status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
736     status += fx_file_open(&ram_disk, &read_only, "TEST.TXT", FX_OPEN_FOR_READ);
737 
738     /* Write 2048 bytes to the file.  */
739     for (i = 0; i < 4096; i++)
740     {
741         /* Write a byte to the file.  */
742         status += fx_file_write(&my_file, " ", 1);
743         status += fx_file_read(&read_only, buffer, 1, &actual);
744     }
745 
746     /* Flush the media.  */
747     status += fx_media_flush(&ram_disk);
748 
749     /* Check the status.  */
750     if (status != FX_SUCCESS)
751     {
752 
753         printf("ERROR!\n");
754         test_control_return(50);
755     }
756 
757     /* Now truncate the file to half the available size, but force an I/O error on the directory entry write.  */
758     _fx_ram_driver_io_error_request =  1;
759     status = fx_file_extended_truncate_release(&my_file, 2048);
760     _fx_ram_driver_io_error_request =  0;
761     if (status != FX_IO_ERROR)
762     {
763         printf("ERROR!\n");
764         test_control_return(51);
765     }
766 
767     /* Now truncate the file with FAT I/O Error.  */
768     _fx_utility_fat_entry_read_error_request =  1;
769     status = fx_file_extended_truncate_release(&my_file, 2000);
770     _fx_utility_fat_entry_read_error_request =  0;
771     if (status != FX_IO_ERROR)
772     {
773         printf("ERROR!\n");
774         test_control_return(52);
775     }
776 
777     /* Now truncate the file with FAT I/O Error.  */
778     _fx_utility_fat_entry_read_error_request =  6;
779     status = fx_file_extended_truncate_release(&my_file, 1900);
780     _fx_utility_fat_entry_read_error_request =  0;
781     if (status != FX_IO_ERROR)
782     {
783         printf("ERROR!\n");
784         test_control_return(53);
785     }
786 
787     /* Now truncate the file with FAT I/O Error.  */
788     _fx_utility_fat_entry_write_error_request =  1;
789     status = fx_file_extended_truncate_release(&my_file, 1700);
790     _fx_utility_fat_entry_write_error_request =  0;
791     if (status != FX_IO_ERROR)
792     {
793         printf("ERROR!\n");
794         test_control_return(54);
795     }
796 
797     /* Now truncate the file with FAT I/O Error.  */
798     _fx_utility_fat_entry_write_error_request =  2;
799     status = fx_file_extended_truncate_release(&my_file, 1500);
800     _fx_utility_fat_entry_write_error_request =  0;
801     if (status != FX_IO_ERROR)
802     {
803         printf("ERROR!\n");
804         test_control_return(55);
805     }
806 
807     /* Now truncate the file with FAT I/O Error.  */
808     _fx_utility_fat_entry_read_error_request =  7;
809     status = fx_file_extended_truncate_release(&my_file, 500);
810     _fx_utility_fat_entry_read_error_request =  0;
811     if (status != FX_IO_ERROR)
812     {
813         printf("ERROR!\n");
814         test_control_return(56);
815     }
816 
817     /* Close everything down.  */
818     status =  fx_file_close(&my_file);
819     status += fx_file_close(&read_only);
820     status += fx_media_close(&ram_disk);
821 
822     /* Check status.  */
823     if (status != FX_SUCCESS)
824     {
825         printf("ERROR!\n");
826         test_control_return(54);
827     }
828 
829     /* Test the cluster values of 1 and fx_media_fat_reserved errors in the FAT chain.  */
830 
831     /* Format the media.  This needs to be done before opening it!  */
832     status =  fx_media_format(&ram_disk,
833                             _fx_ram_driver,         // Driver entry
834                             ram_disk_memory,        // RAM disk memory pointer
835                             cache_buffer,           // Media buffer pointer
836                             CACHE_SIZE,             // Media buffer size
837                             "MY_RAM_DISK",          // Volume Name
838                             1,                      // Number of FATs
839                             32,                     // Directory Entries
840                             0,                      // Hidden sectors
841                             18000,                  // Total sectors
842                             128,                    // Sector size
843                             3,                      // Sectors per cluster
844                             1,                      // Heads
845                             1);                     // Sectors per track
846 
847     /* Determine if the format had an error.  */
848     if (status)
849     {
850 
851         printf("ERROR!\n");
852         test_control_return(55);
853     }
854 
855     /* Open the ram_disk.  */
856     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, 128);
857 
858     /* Check the status.  */
859     if (status != FX_SUCCESS)
860     {
861 
862         /* Error, return error code.  */
863         printf("ERROR!\n");
864         test_control_return(56);
865     }
866 
867     /* Create a file called TEST.TXT in the root directory.  */
868     status =  fx_file_create(&ram_disk, "TEST.TXT");
869 
870     /* Check the create status.  */
871     if (status != FX_SUCCESS)
872     {
873 
874         printf("ERROR!\n");
875         test_control_return(57);
876     }
877 
878     /* Open the test file.  */
879     status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
880     status += fx_file_open(&ram_disk, &read_only, "TEST.TXT", FX_OPEN_FOR_READ);
881 
882     /* Write 2048 bytes to the file.  */
883     for (i = 0; i < 4096; i++)
884     {
885         /* Write a byte to the file.  */
886         status += fx_file_write(&my_file, " ", 1);
887         status += fx_file_read(&read_only, buffer, 1, &actual);
888     }
889 
890     /* Flush the media.  */
891     status += fx_media_flush(&ram_disk);
892 
893     /* Check the status.  */
894     if (status != FX_SUCCESS)
895     {
896 
897         printf("ERROR!\n");
898         test_control_return(58);
899     }
900 
901     /* Now truncate one byte of the file.  */
902     status = fx_file_extended_truncate_release(&my_file, 4095);
903 
904     if (status != FX_SUCCESS)
905     {
906         printf("ERROR!\n");
907         test_control_return(59);
908     }
909 
910 
911     /* Now truncate the file but force a FAT entry of 1.  */
912     _fx_utility_fat_entry_read_error_request =  10005;
913     status = fx_file_extended_truncate_release(&my_file, 4094);
914     _fx_utility_fat_entry_read_error_request =  0;
915     if (status != FX_FILE_CORRUPT)
916     {
917         printf("ERROR!\n");
918         test_control_return(60);
919     }
920 
921     /* Now truncate the file but force a FAT entry of max value.  */
922     _fx_utility_fat_entry_read_error_request =  20005;
923     status = fx_file_extended_truncate_release(&my_file, 4093);
924     _fx_utility_fat_entry_read_error_request =  0;
925     if (status != FX_FILE_CORRUPT)
926     {
927         printf("ERROR!\n");
928         test_control_return(61);
929     }
930 
931     /* Now truncate the file but force a FAT entry of 1 to the traversal of releasing clusters.  */
932     _fx_utility_fat_entry_read_error_request =  10012;
933     status = fx_file_extended_truncate_release(&my_file, 4092);
934     _fx_utility_fat_entry_read_error_request =  0;
935     if (status != FX_SUCCESS)
936     {
937         printf("ERROR!\n");
938         test_control_return(62);
939     }
940 
941     /* Now truncate the file but force a FAT entry of 1 in the traversal of open files.  */
942     _fx_utility_fat_entry_read_error_request =  10025;
943     status = fx_file_extended_truncate_release(&my_file, 4091);
944     _fx_utility_fat_entry_read_error_request =  0;
945     if (status != FX_FILE_CORRUPT)
946     {
947         printf("ERROR!\n");
948         test_control_return(63);
949     }
950 
951     /* Now truncate the file but force a FAT entry of 1 in the traversal of open files.  */
952     _fx_utility_fat_entry_read_error_request =  20025;
953     status = fx_file_extended_truncate_release(&my_file, 4090);
954     _fx_utility_fat_entry_read_error_request =  0;
955     if (status != FX_FILE_CORRUPT)
956     {
957         printf("ERROR!\n");
958         test_control_return(64);
959     }
960 
961     /* Close everything down.  */
962     status =  fx_file_close(&my_file);
963     status += fx_file_close(&read_only);
964     status += fx_media_close(&ram_disk);
965 
966     /* Check status.  */
967     if (status != FX_SUCCESS)
968     {
969         printf("ERROR!\n");
970         test_control_return(63);
971     }
972 
973     /* Test file extended truncate corner cases.  */
974 
975     /* Format the media.  This needs to be done before opening it!  */
976     status =  fx_media_format(&ram_disk,
977                             _fx_ram_driver,         // Driver entry
978                             ram_disk_memory,        // RAM disk memory pointer
979                             cache_buffer,           // Media buffer pointer
980                             CACHE_SIZE,             // Media buffer size
981                             "MY_RAM_DISK",          // Volume Name
982                             1,                      // Number of FATs
983                             32,                     // Directory Entries
984                             0,                      // Hidden sectors
985                             18000,                  // Total sectors
986                             128,                    // Sector size
987                             3,                      // Sectors per cluster
988                             1,                      // Heads
989                             1);                     // Sectors per track
990 
991     /* Determine if the format had an error.  */
992     if (status)
993     {
994 
995         printf("ERROR!\n");
996         test_control_return(64);
997     }
998 
999     /* Open the ram_disk.  */
1000     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, 128);
1001 
1002     /* Check the status.  */
1003     if (status != FX_SUCCESS)
1004     {
1005 
1006         /* Error, return error code.  */
1007         printf("ERROR!\n");
1008         test_control_return(65);
1009     }
1010 
1011     /* Create a file called TEST.TXT in the root directory.  */
1012     status =  fx_file_create(&ram_disk, "TEST.TXT");
1013     status += fx_file_create(&ram_disk, "TEST1.TXT");
1014     status += fx_file_create(&ram_disk, "TEST2.TXT");
1015     status += fx_file_create(&ram_disk, "TEST3.TXT");
1016     status += fx_file_create(&ram_disk, "TEST4.TXT");
1017     status += fx_file_create(&ram_disk, "TEST5.TXT");
1018     status += fx_file_create(&ram_disk, "TEST6.TXT");
1019     status += fx_file_create(&ram_disk, "TEST7.TXT");
1020     status += fx_file_create(&ram_disk, "TEST8.TXT");
1021     status += fx_file_create(&ram_disk, "TEST9.TXT");
1022     status += fx_file_create(&ram_disk, "TEST10.TXT");
1023     status += fx_file_create(&ram_disk, "TEST11.TXT");
1024     status += fx_file_create(&ram_disk, "TEST12.TXT");
1025     status += fx_file_create(&ram_disk, "TEST13.TXT");
1026     status += fx_file_create(&ram_disk, "TEST14.TXT");
1027     status += fx_file_create(&ram_disk, "TEST15.TXT");
1028     status += fx_file_create(&ram_disk, "TEST16.TXT");
1029     status += fx_file_create(&ram_disk, "TEST17.TXT");
1030     status += fx_file_create(&ram_disk, "TEST18.TXT");
1031     status += fx_file_create(&ram_disk, "TEST19.TXT");
1032     status += fx_file_create(&ram_disk, "TEST20.TXT");
1033     status += fx_file_create(&ram_disk, "TEST21.TXT");
1034     status += fx_file_create(&ram_disk, "TEST22.TXT");
1035     status += fx_file_create(&ram_disk, "TEST23.TXT");
1036     status += fx_file_create(&ram_disk, "TEST24.TXT");
1037     status += fx_file_create(&ram_disk, "TEST25.TXT");
1038     status += fx_file_create(&ram_disk, "TEST26.TXT");
1039     status += fx_file_create(&ram_disk, "TEST27.TXT");
1040     status += fx_file_create(&ram_disk, "TEST28.TXT");
1041     status += fx_file_create(&ram_disk, "TEST29.TXT");
1042     status += fx_file_create(&ram_disk, "TEST30.TXT");
1043 
1044 
1045     /* Check the create status.  */
1046     if (status != FX_SUCCESS)
1047     {
1048 
1049         printf("ERROR!\n");
1050         test_control_return(67);
1051     }
1052 
1053     /* Open the test file.  */
1054     status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
1055     status += fx_file_open(&ram_disk, &read_only, "TEST.TXT", FX_OPEN_FOR_READ);
1056     status += fx_file_open(&ram_disk, &my_file1, "TEST1.TXT", FX_OPEN_FOR_WRITE);
1057     status += fx_file_open(&ram_disk, &my_file2, "TEST30.TXT", FX_OPEN_FOR_WRITE);
1058 
1059     /* Write 2048 bytes to the file.  */
1060     for (i = 0; i < 4096; i++)
1061     {
1062         /* Write a byte to the file.  */
1063         status += fx_file_write(&my_file, " ", 1);
1064         status += fx_file_read(&read_only, buffer, 1, &actual);
1065     }
1066 
1067     /* Flush the media.  */
1068     status += fx_media_flush(&ram_disk);
1069 
1070     /* Check the status.  */
1071     if (status != FX_SUCCESS)
1072     {
1073 
1074         printf("ERROR!\n");
1075         test_control_return(68);
1076     }
1077 
1078     /* Now truncate one byte of the file.  */
1079     status = fx_file_extended_truncate(&my_file, 4095);
1080 
1081     if (status != FX_SUCCESS)
1082     {
1083         printf("ERROR!\n");
1084         test_control_return(69);
1085     }
1086 
1087     /* Seek to make the file offset less than our new truncate size.  */
1088     status =  fx_file_seek(&my_file, 4094);
1089 
1090     /* Truncate another byte of the file.  */
1091     status = fx_file_extended_truncate(&my_file, 4094);
1092 
1093     if (status != FX_SUCCESS)
1094     {
1095         printf("ERROR!\n");
1096         test_control_return(70);
1097     }
1098 
1099     /* Now truncate the another byte of the file, but with a FAT read error.  */
1100     _fx_utility_fat_entry_read_error_request =  1;
1101     status = fx_file_extended_truncate(&my_file, 4093);
1102     _fx_utility_fat_entry_read_error_request =  0;
1103     if (status != FX_IO_ERROR)
1104     {
1105         printf("ERROR!\n");
1106         test_control_return(71);
1107     }
1108 
1109 
1110     /* Now truncate the file but force a FAT entry of 1.  */
1111     _fx_utility_fat_entry_read_error_request =  10003;
1112     status = fx_file_extended_truncate(&my_file, 4092);
1113     _fx_utility_fat_entry_read_error_request =  0;
1114     if (status != FX_FILE_CORRUPT)
1115     {
1116         printf("ERROR!\n");
1117         test_control_return(72);
1118     }
1119 
1120     /* Now truncate the file but force a FAT entry of max value.  */
1121     _fx_utility_fat_entry_read_error_request =  20003;
1122     status = fx_file_extended_truncate(&my_file, 4091);
1123     _fx_utility_fat_entry_read_error_request =  0;
1124     if (status != FX_FILE_CORRUPT)
1125     {
1126         printf("ERROR!\n");
1127         test_control_return(73);
1128     }
1129 
1130     /* Close everything down.  */
1131     status =  fx_file_close(&my_file);
1132     status += fx_file_close(&my_file1);
1133     status += fx_file_close(&my_file2);
1134     status += fx_file_close(&read_only);
1135     status += fx_media_close(&ram_disk);
1136 
1137     /* Check status.  */
1138     if (status != FX_SUCCESS)
1139     {
1140         printf("ERROR!\n");
1141         test_control_return(74);
1142     }
1143     else
1144     {
1145 
1146         printf("SUCCESS!\n");
1147         test_control_return(0);
1148     }
1149 }
1150 
1151