fsdosfsname01: Add compatibility tests

Test handling of file names and directory names according to Microsofts
specification for the FAT file system. Tests for compatibility with a
genuine MS Windows FAT file system have been added.
This commit is contained in:
Ralf Kirchner
2013-02-26 15:58:42 +01:00
committed by Sebastian Huber
parent 52f3aa0519
commit e1483973c4
6 changed files with 11294 additions and 0 deletions

View File

@@ -0,0 +1,150 @@
/**
* @file Create_Files.cs
*
* @brief Format a USB memory stick and create files on the stick
* Small C# application which formats a USB memory stick with a FAT
* file system and creates files on the memory stick. The files will
* have names with various multibyte strings.
* The whole procedure is part of creating a MS Windows FAT disk image
* whith files with exotic multibyte filenames. The image will get
* mounted under RTEMS for testing the mutibyte/UTF-8 feature of the
* RTEMS FAT file system and the compatibility to MS Windows.
*/
/*
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Text;
namespace Create_Files
{
public static class Create_Files
{
// Strings for file names and file contents
public static string[] Strings = new string[] {
"this is a long filename",
"đây là một tên tập tin dài",
"Bu uzun bir dosya adı",
"هذا هو اسم ملف طويل",
"αυτό είναι ένα μεγάλο όνομα αρχείου",
"это длинное имя",
"гэта доўгае імя",
"това е дълго име на файла",
"这是一个长文件名",
"মেৰিকা মহাদেশ, উত্তৰ আমেৰিকা আৰু দক্ষিণ আমেৰিকা মহাদেশক লৈ গঠিত এক",
"آمریکا قاره یکته قارهٰ زمینˇ قاره‌ٰنˇ مئن ایسسه کی زمینˇ هنه‌شر (مساحت)ˇ جی ۳۸٪ و زمینˇ خوشکی‌ئنˇ جی ۴۲۸٪ ای قاره شی ایسسه",
"Manâhestôtse 910,720,588 (July 2008 est.)",
"Elle s'étend depuis l'océan Arctique au nord jusqu'au cap Horn dans le passage de Drake au sud, à la confluence des océans",
"ཨ་མེ་རི་ཀ, ཨ་མེ་རི་ཁ, མེ་གླིང་",
"е су земље западне хемисфере или Новог света које се састоје од континената Северна Америка",
"This is a filename with with 255 characters. The following numbers are aligned in that way, that the character 0 is the mentioned one. xx140xxxxxxx150xxxxxxx160xxxxxxx170xxxxxxx180xxxxxxx190xxxxxxx200xxxxxxx210xxxxxxx220xxxxxxx230xxxxxxx240xxxxxxx250xxxxx",
"Bu gezegen Roma mitolojisindeki savaş ilahı Mars'a",
"Amerike su zemlje zapadne hemisfere ili Novog svijeta koje se sastoje od kontinenata Sjeverna Amerika i Južna Amerika sa svim pridruženim otocima i regijama.",
"იანებს ორ კონტინენტს, სამხრეთ და ჩრდილოეთ ამერიკას ახლომდებარე კუნძულებთან ერ",
" Є то єдиный контінент, котрого цїла теріторія лежыть на Западній півкулї тай разом"
};
// Use the features of MS Windows to format the USB memory stick. We want a genuine Microsoft FAT file system
public static void FormatDrive(string driveLetter)
{
ProcessStartInfo StartInfo = new ProcessStartInfo();
StartInfo.FileName = Environment.SystemDirectory + "\\cmd.exe";
StartInfo.Arguments = "/C \"format " + driveLetter + " /FS:FAT\"";
StartInfo.UseShellExecute = false;
StartInfo.RedirectStandardInput = true;
Process Process = Process.Start(StartInfo);
//Thread.Sleep(1000);
Process.StandardInput.WriteLine();
Process.StandardInput.WriteLine();
Process.WaitForExit();
}
// Format a USB meory stick and create files on the new volume
// args[0] The drive to be formatted. E.g. "e:"
public static void Main(string[] args)
{
// Display help text on the console
if ((args.Length <= 0) || (args[0].Equals("-h", StringComparison.InvariantCultureIgnoreCase) || args[0].Equals("-help", StringComparison.InvariantCultureIgnoreCase)))
{
Console.WriteLine("create_files.bat <DRIVE>");
Console.WriteLine("Will format DRIVE and create files on the new formated drive.");
}
else
{
// Show a warning
Console.WriteLine(args[0] + " will get formated!");
while (true)
{
Console.WriteLine("Press y to continue or press n to abort. [y\\n]");
string Input = Console.ReadLine();
if (Input[0].Equals('y') || Input[0].Equals('Y'))
break;
else if (Input[0].Equals('n') || Input[0].Equals('N'))
return;
}
// Format the USB memory stick
FormatDrive(args[0]);
// Create the files and write their own file names into them
for (int i = 0; i < Strings.GetLength(0); i++)
{
File.WriteAllText(Path.Combine(args[0], Strings[i]), Strings[i], Encoding.UTF8);
Console.WriteLine("The file \"" + Strings[i] + "\" created.");
}
// Create a c header file which contains an array with the strings and a #define
// for the number of strings
string HeaderPath = Path.Combine(args[0]/*Environment.CurrentDirectory*/, "files.h");
Console.WriteLine("The header \"" + HeaderPath + "\" will write.");
StreamWriter HeaderStream = new StreamWriter(HeaderPath);
HeaderStream.Write("\n" +
"/*\n" +
" * Array with files, that were created in the FAT-filesystem image.bin.\n" +
" *\n" +
" * WARNING: Automatically generated by Create_Files.cs -- do not edit!\n" +
" */\n" +
"\n" +
"#ifndef __FILE_H__\n" +
"#define __FILE_H__\n" +
"\n" +
"#ifdef __cplusplus\n" +
"extern C {\n" +
"#endif\n" +
"\n" +
"static const char *const filenames[] = {\n");
for (int i = 0; i < Strings.GetLength(0); i++)
HeaderStream.WriteLine(" \"" + Strings[i] + ((i == (Strings.GetLength(0) - 1)) ? "\"" : "\","));
string NumberOfFilesStr = Strings.GetLength(0).ToString(System.Globalization.CultureInfo.InvariantCulture);
HeaderStream.Write("};\n" +
"#define FILES_FILENAMES_NUMBER_OF " + NumberOfFilesStr + "\n" +
"\n" +
"#ifdef __cplusplus\n" +
"}\n" +
"#endif\n" +
"\n" +
"#endif /* __FILE_H__ */\n" +
"\n");
// Finalize
HeaderStream.Flush();
HeaderStream.Close();
HeaderStream.Dispose();
}
}
}
}

View File

@@ -0,0 +1,42 @@
#!/bin/sh
# Copyright (c) 2013 embedded brains GmbH.
#
# The license and distribution terms for this file may be
# found in the file LICENSE in this distribution or at
# http://www.rtems.com/license/LICENSE.
IMAGE=image
IMAGE_BIN=$IMAGE.bin
FILES_H=files.h
MNT=create_image_mnt
if [ -e "$1" ]
then
rm -r -f $MNT
sudo umount "$1"
mkdir $MNT
sudo mount -t msdos "$1" $MNT
sleep 2
sudo mv "$MNT/$FILES_H" ./$FILES_H
sudo touch ./$FILES_H
sudo umount $MNT
rmdir $MNT
sudo dd if="$1" of="$IMAGE_BIN"
/opt/rtems-4.11/bin/rtems-bin2c -C -c "$IMAGE_BIN" "$IMAGE"
mv "$IMAGE".c "$IMAGE".h
rm -f "$IMAGE_BIN"
else
echo ""
echo "$0 <DEV_NAME>"
echo "Will move file \"files.h\" from the device DEV_NAME to the current directory"
echo "and will then create an image of device DEV_NAME and convert the"
echo "image to file image.h in the current directory."
echo ""
echo "This script is intended to be used with USB memory sticks written by"
echo "application create_fat_test_image/Create_Files under MS Windows"
echo ""
fi

View File

@@ -0,0 +1,44 @@
/*
* Array with files, that were created in the FAT-filesystem image.bin.
*
* WARNING: Automatically generated by Create_Files.cs -- do not edit!
*/
#ifndef __FILE_H__
#define __FILE_H__
#ifdef __cplusplus
extern C {
#endif
static const char *const filenames[] = {
"this is a long filename",
"đây là một tên tập tin dài",
"Bu uzun bir dosya adı",
"هذا هو اسم ملف طويل",
"αυτό είναι ένα μεγάλο όνομα αρχείου",
"это длинное имя",
"гэта доўгае імя",
"това е дълго име на файла",
"这是一个长文件名",
"মেৰিকা মহাদেশ, উত্তৰ আমেৰিকা আৰু দক্ষিণ আমেৰিকা মহাদেশক লৈ গঠিত এক",
"آمریکا قاره یکته قارهٰ زمینˇ قاره‌ٰنˇ مئن ایسسه کی زمینˇ هنه‌شر (مساحت)ˇ جی ۳۸٪ و زمینˇ خوشکی‌ئنˇ جی ۴۲۸٪ ای قاره شی ایسسه",
"Manâhestôtse 910,720,588 (July 2008 est.)",
"Elle s'étend depuis l'océan Arctique au nord jusqu'au cap Horn dans le passage de Drake au sud, à la confluence des océans",
"ཨ་མེ་རི་ཀ, ཨ་མེ་རི་ཁ, མེ་གླིང་",
"е су земље западне хемисфере или Новог света које се састоје од континената Северна Америка",
"This is a filename with with 255 characters. The following numbers are aligned in that way, that the character 0 is the mentioned one. xx140xxxxxxx150xxxxxxx160xxxxxxx170xxxxxxx180xxxxxxx190xxxxxxx200xxxxxxx210xxxxxxx220xxxxxxx230xxxxxxx240xxxxxxx250xxxxx",
"Bu gezegen Roma mitolojisindeki savaş ilahı Mars'a",
"Amerike su zemlje zapadne hemisfere ili Novog svijeta koje se sastoje od kontinenata Sjeverna Amerika i Južna Amerika sa svim pridruženim otocima i regijama.",
"იანებს ორ კონტინენტს, სამხრეთ და ჩრდილოეთ ამერიკას ახლომდებარე კუნძულებთან ერ",
" Є то єдиный контінент, котрого цїла теріторія лежыть на Западній півкулї тай разом"
};
#define FILES_FILENAMES_NUMBER_OF 20
#ifdef __cplusplus
}
#endif
#endif /* __FILE_H__ */

View File

@@ -17,3 +17,4 @@ directives:
concepts:
- Make sure short file- and directory names and long file- and directory names are handled correctly for the default character set (code page 850)
- Make sure multibyte file names and directory names are handled correctly
- Make sure the RTEMS FAT file system is compatible with a genuine MS Windows FAT file system

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,8 @@
#include <rtems/ramdisk.h>
#include <rtems/libcsupport.h>
#include "ramdisk_support.h"
#include "image.h"
#include "files.h"
#define MOUNT_DIR "/mnt"
#define MOUNT_DIR_SIZE 4
@@ -43,11 +45,23 @@
#define MAX_NAME_LENGTH ( 255 + 1 )
#define MAX_NAME_LENGTH_INVALID ( 255 + 2 )
#define MAX_DUPLICATES_PER_NAME 3
static const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
#define UTF8_BOM_SIZE 3 /* Size of the UTF-8 byte-order-mark */
#define BLOCK_SIZE 512
#define BLOCK_COUNT ( sizeof( image_bin ) / BLOCK_SIZE )
static ramdisk disk_image = {
.block_size = BLOCK_SIZE,
.block_num = BLOCK_COUNT,
.area = &image_bin[0],
.initialized = true,
.malloced = false,
.trace = false,
.free_at_delete_request = false
};
static rtems_resource_snapshot before_mount;
static const msdos_format_request_param_t rqdata = {
@@ -709,6 +723,112 @@ static void test_finding_directories(
rtems_test_assert( rc == 0 );
}
/*
* Test the compatibility with a genuine MS Windows FAT file system.
*/
static void test_compatibility( void )
{
int rc;
rtems_status_code sc;
dev_t dev;
char diskpath[] = "/dev/ramdisk1";
rtems_dosfs_mount_options mount_opts;
rtems_device_major_number major;
FILE *fp;
int buffer;
unsigned int index_file = 0;
unsigned int index_char;
unsigned int offset;
char content_buf[MAX_NAME_LENGTH + strlen( MOUNT_DIR )
+ 1];
char file_path[MAX_NAME_LENGTH + strlen( MOUNT_DIR )
+ 1];
DIR *dir_stream;
struct dirent *dp;
mount_opts.converter = rtems_dosfs_create_utf8_converter( "CP850" );
rtems_test_assert( mount_opts.converter != NULL );
sc = rtems_io_register_driver( 0, &ramdisk_ops, &major );
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
dev = rtems_filesystem_make_dev_t( major, 1 );
sc = rtems_disk_create_phys(
dev,
BLOCK_SIZE,
BLOCK_COUNT,
ramdisk_ioctl,
&disk_image,
diskpath );
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
rc = mount_and_make_target_path(
diskpath,
MOUNT_DIR,
RTEMS_FILESYSTEM_TYPE_DOSFS,
RTEMS_FILESYSTEM_READ_WRITE,
&mount_opts );
rtems_test_assert( rc == 0 );
dir_stream = opendir( MOUNT_DIR );
rtems_test_assert( dir_stream != NULL );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
while ( dp != NULL ) {
index_char = 0;
size_t len = strlen( filenames[index_file] );
if ( filenames[index_file][len - 1] == '.' )
rtems_test_assert( ( len - 1 ) == dp->d_namlen );
else
rtems_test_assert( len == dp->d_namlen );
rtems_test_assert( 0
== memcmp( &filenames[index_file][0], &dp->d_name[0],
dp->d_namlen ) );
snprintf( file_path, sizeof( file_path ), "%s/%s", MOUNT_DIR,
filenames[index_file] );
fp = fopen( file_path, "r" );
rtems_test_assert( fp != NULL );
/* These files should contain their own file names. */
while ( ( buffer = fgetc( fp ) ) != EOF ) {
content_buf[index_char] = buffer;
++index_char;
}
if ( 0 == strncmp( content_buf, UTF8_BOM, UTF8_BOM_SIZE ) )
offset = UTF8_BOM_SIZE;
else
offset = 0;
rtems_test_assert( 0
== memcmp( filenames[index_file],
&content_buf[offset],
index_char - offset ) );
rc = fclose( fp );
rtems_test_assert( rc == 0 );
++index_file;
dp = readdir( dir_stream );
}
rtems_test_assert( index_file == FILES_FILENAMES_NUMBER_OF );
rc = closedir( dir_stream );
rtems_test_assert( rc == 0 );
rc = unmount( MOUNT_DIR );
rtems_test_assert( rc == 0 );
}
/*
* Main test method
*/
@@ -879,6 +999,8 @@ static void test( void )
unmount_and_close_device();
test_compatibility();
del_ramdisk();
}