8

私は実際に DiskUtils でファット ディスク イメージを抽出しようとしていますが、正しいファイル名を取得していません...

「\TURNEROVER\TOPPERSHEATH.PPTX」の代わりに「\TURNER~3\TOPPER~1.P~1」が表示されます

FatFileSystem FatImg = new FatFileSystem(MS); //MS = Fat Image MemoryStream
foreach(DiscDirectoryInfo Di in FatImg.Root.GetDirectories())
{
    foreach(DiscFileInfo Fi in Di.GetFiles())
    {
        Stream St = Fi.OpenRead(); // Correct Stream
        string FName = Fi.Name; //Wrong Name
    }
}

これは、DiscUtils が LFN [長いファイル名] をサポートしていないためです...

だから私は自分で作成しようとする前にこれらのファイルを抽出するための完璧なライブラリを探しています...

FileNameエラーなしで[おそらくDiscUtilsで]抽出できる方法はありますか...

4

5 に答える 5

3

DiscUtilsをサポートするために追加できるいくつかの変更を次に示しますFAT LFN

Fat\Directory.csまず、次のようにファイルにこれらの変更を加えます (_lfns変数と関数を追加しGetLfnChunk、既存のLoadEntries関数を変更して、以下でマークされた行を追加する必要があり//+++ます)。

internal Dictionary<string, string> _lfns = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

private static string GetLfnChunk(byte[] buffer)
{
    // see http://home.teleport.com/~brainy/lfn.htm
    // NOTE: we assume ordinals are ok here.
    char[] chars = new char[13];
    chars[0] = (char)(256 * buffer[2] + buffer[1]);
    chars[1] = (char)(256 * buffer[4] + buffer[3]);
    chars[2] = (char)(256 * buffer[6] + buffer[5]);
    chars[3] = (char)(256 * buffer[8] + buffer[7]);
    chars[4] = (char)(256 * buffer[10] + buffer[9]);

    chars[5] = (char)(256 * buffer[15] + buffer[14]);
    chars[6] = (char)(256 * buffer[17] + buffer[16]);
    chars[7] = (char)(256 * buffer[19] + buffer[18]);
    chars[8] = (char)(256 * buffer[21] + buffer[20]);
    chars[9] = (char)(256 * buffer[23] + buffer[22]);
    chars[10] = (char)(256 * buffer[25] + buffer[24]);

    chars[11] = (char)(256 * buffer[29] + buffer[28]);
    chars[12] = (char)(256 * buffer[31] + buffer[30]);
    string chunk = new string(chars);
    int zero = chunk.IndexOf('\0');
    return zero >= 0 ? chunk.Substring(0, zero) : chunk;
}

private void LoadEntries()
{
    _entries = new Dictionary<long, DirectoryEntry>();
    _freeEntries = new List<long>();

    _selfEntryLocation = -1;
    _parentEntryLocation = -1;

    string lfn = null;  //+++
    while (_dirStream.Position < _dirStream.Length)
    {
        long streamPos = _dirStream.Position;
        DirectoryEntry entry = new DirectoryEntry(_fileSystem.FatOptions, _dirStream);

        if (entry.Attributes == (FatAttributes.ReadOnly | FatAttributes.Hidden | FatAttributes.System | FatAttributes.VolumeId))
        {
            // Long File Name entry
            _dirStream.Position = streamPos;  //+++
            lfn = GetLfnChunk(Utilities.ReadFully(_dirStream, 32)) + lfn;  //+++
        }
        else if (entry.Name.IsDeleted())
        {
            // E5 = Free Entry
            _freeEntries.Add(streamPos);
            lfn = null; //+++
        }
        else if (entry.Name == FileName.SelfEntryName)
        {
            _selfEntry = entry;
            _selfEntryLocation = streamPos;
            lfn = null; //+++
        }
        else if (entry.Name == FileName.ParentEntryName)
        {
            _parentEntry = entry;
            _parentEntryLocation = streamPos;
            lfn = null; //+++
        }
        else if (entry.Name == FileName.Null)
        {
            // Free Entry, no more entries available
            _endOfEntries = streamPos;
            lfn = null; //+++
            break;
        }
        else
        {
            if (lfn != null) //+++
            { //+++
                _lfns.Add(entry.Name.GetDisplayName(_fileSystem.FatOptions.FileNameEncoding), lfn); //+++
            } //+++
            _entries.Add(streamPos, entry);
            lfn = null; //+++
        }
    }
}

次に、これら 2 つのパブリック関数をファイルに追加しFat\FatFileSystem.csます。これらは、LFN でクエリを実行する新しい API になります。

/// <summary>
/// Gets the long name of a given file.
/// </summary>
/// <param name="shortFullPath">The short full path to the file. Input path segments must be short names.</param>
/// <returns>The corresponding long file name.</returns>
public string GetLongFileName(string shortFullPath)
{
    if (shortFullPath == null)
        throw new ArgumentNullException("shortFullPath");

    string dirPath = Path.GetDirectoryName(shortFullPath);
    string fileName = Path.GetFileName(shortFullPath);
    Directory dir = GetDirectory(dirPath);
    if (dir == null)
        return fileName;

    string lfn;
    if (dir._lfns.TryGetValue(Path.GetFileName(shortFullPath), out lfn))
        return lfn;

    return fileName;
}

/// <summary>
/// Gets the long path to a given file.
/// </summary>
/// <param name="shortFullPath">The short full path to the file. Input path segments must be short names.</param>
/// <returns>The corresponding long file path to the file or null if not found.</returns>
public string GetLongFilePath(string shortFullPath)
{
    if (shortFullPath == null)
        throw new ArgumentNullException("shortFullPath");

    string path = null;
    string current = null;
    foreach (string segment in shortFullPath.Split(Path.DirectorySeparatorChar))
    {
        if (current == null)
        {
            current = segment;
            path = GetLongFileName(current);
        }
        else
        {
            current = Path.Combine(current, segment);
            path = Path.Combine(path, GetLongFileName(current));
        }
    }
    return path;
}

以上です。これで、FAT ディスク全体を次のように再帰的にダンプできるようになります。たとえば、次のようになります。

static void Main(string[] args)
{
    using (FileStream fs = File.Open("fat.ima", FileMode.Open))
    {
        using (FatFileSystem floppy = new FatFileSystem(fs))
        {
            Dump(floppy.Root);
        }
    }
}

static void Dump(DiscDirectoryInfo di)
{
    foreach (DiscDirectoryInfo subdi in di.GetDirectories())
    {
        Dump(subdi);
    }
    foreach (DiscFileInfo fi in di.GetFiles())
    {
        Console.WriteLine(fi.FullName);
        // get LFN name
        Console.WriteLine(" " + ((FatFileSystem)di.FileSystem).GetLongFileName(fi.FullName));


        // get LFN-ed full path
        Console.WriteLine(" " + ((FatFileSystem)di.FileSystem).GetLongFilePath(fi.FullName));
    }
}

ご自身の責任で使用してください。:)

于 2012-05-22T08:02:19.370 に答える
2

7-Zipは FAT イメージを抽出できます。ファイル名を読み取ってストリームに抽出できるC# ラッパー ライブラリがhttp://sevenzipsharp.codeplex.comにあります。

于 2012-05-10T10:10:14.437 に答える
1

DiscUtils では、FAT のロング ネーム ファイルはサポートされていないようです。 この投稿をチェックしてください。あなたが質問したように見えるので、あなたは知っていると確信しています。

于 2012-05-16T13:48:11.063 に答える
0

/X スイッチを指定した DOS DIR コマンドは、長い名前と短い名前の両方を表示します。

それ以外の場合は、LFN を保存するためのユーティリティがあります。マッピング テーブルの作成に役立つDOSLFNBk.exeです。

あなたが探していた答えはわかりませんが、最初にテーブルを手動で作成してDiskUtilなしでマッピングを行うことはできません。あなたの目的を達成するためのユーティリティや方法は考えられません-しかし、あなたが言及したように、SO誰か代替案を知っているかもしれません。

DiskUtils の Kevin は、LFN のサポートを含めると Mirosoft の特許を侵害することになると述べていましたが、侵害することを提案しているわけではありません (商業プロジェクトではないことは間違いありません)。 7-Zipにはライセンスがあります...

あなたのスクリーンショットは VNext を示しています..RTM バージョンと同じエラーですか?

于 2012-05-18T10:25:18.730 に答える