2012-05-10 28 views
6

我實際上試圖用DiskUtils提取FAT磁盤映像,但我沒有得到正確的文件名...c# - 我如何提取FAT磁盤映像?

我得到「\ TURNER〜3 \ TOPPER〜1.P〜1」來代替「 \ TURNEROVER \ TOPPERSHEATH.PPTX」

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 [長文件名] ...

所以我在尋找一個完美的庫befor我嘗試提取這些文件讓我自己...

有沒有我可以提取它[也許通過DiscUtils]沒有FileName錯誤...

+0

你有一個現有的FAT映像文件在某處,我們可以玩嗎? –

+1

獲取[Sample Fat Image](http://www.mediafire.com/?qbnjw7d3c77er15) – Writwick

回答

3

下面是一些修改,您可以添加到DiscUtils支持FAT LFN S:

首先,這些更改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; //+++ 
     } 
    } 
} 

其次,添加這兩個公共功能爲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; 
} 

就是這樣。現在,你會能遞歸轉儲全脂盤這樣的,例如:在你自己的風險

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)); 
    } 
} 

使用!:)

+0

是你這方面的工作?一旦賞金結束,我已經決定編輯'DiscUtils'文件!反正謝謝! + 60 [賞金+10(+1)]一旦賞金結束! – Writwick

+0

@WritwickDas - 不,但我發現這個挑戰很有趣,而我是一個賞金獵人:-) –

+0

賞金轉到'賞金獵人! – Writwick

2

7-Zip可以提取FAT圖像。有一個C#包裝庫http://sevenzipsharp.codeplex.com可以讀取文件名並提取到流。

+0

你確定它可以提取任何類型的脂肪? 說FAT16或FAT12 ......我有我試圖與桂開了FAT16文件,但它報告無效存檔... 的錯誤,但我會嘗試... [我瞭解SevenZipSharp從之前但是作爲7-Zip本身無法打開文件我沒有嘗試] – Writwick

+0

我用它與軟盤映像,它有vhd硬盤映像支持,所以我期望它可以提取任何類型的FAT。 –

+0

準確的錯誤是**「無法打開'FileName'作爲存檔!」** 剛剛檢查! WinImage可以正確編輯我擁有的脂肪! – Writwick

1

似乎在DiscUtils中沒有對FAT的長名稱文件支持。 Check out this post.我相信你知道,因爲它看起來像你問的問題。

+0

你說得對,我問那裏的問題。所以我在這裏問任何替代我的思念.... – Writwick

0

帶有/ X開關的DOS DIR命令顯示長名和短名。

否則,是一種實用工具,以節省LFNs:DOSLFNBk.exe將與創建的映射表幫助。

我不知道你在尋找,但短期手動首先創建一個表,所以你可以不用磁盤工具映射的答案,我想不出一個實用程序或方法來實現自己的目標 - 但你提,在這裏,有人可能會知道另一種選擇。

DiskUtils的Kevin確實提到如果他包含對LFN的支持,他會侵犯Mirosoft專利,我並不是暗示你侵犯了其中任何一項(肯定不是它的一個計劃項目),但如果這僅僅是個人的或者可以的話找到類似7-Zip的圖書館有許可證...

您的屏幕截圖顯示了VNext ..與RTM版本有相同的錯誤?

+0

你是什麼意思_「你的屏幕截圖顯示VNext ..同樣的錯誤與RTM版本?」我_沒有得到這個句子...我怎麼能運行DOS DIR命令與FAT光盤鏡像上的/ X開關?? ...和AFAIK,DOS的LFN備份不是免費的[我發現這個工具之前,但不知道[沒有使用它,因爲它不是免費的],而不是可用的光盤映像.. Anyway謝謝你的建議.. – Writwick

+0

現在檢查,DOSLFNBK有一個免費版本1.6,但該版本不支持FAT32 ......來到FAT32的2.0版和2.3 – Writwick

+0

vNext == VS 2011之間,對不起下次我會投入更多researh –

0

在命令行的最好的方法是使用這樣的:

7Z的 「e」 +源+ 「-o」 +路徑+ 「* -r」

  • 「e」 的=提取
  • 源=路徑磁盤映像
  • 「-o」=輸出/提取到
  • 路徑=目標提取到
  • 「*」=所有文件
  • 「-r」 =遞歸

在C#中,你可以用這個方法我做(我複製7z.exe我的應用程序的調試文件夾)

public void ExtractDiskImage(string pathToDiskImage, string extractPath, bool WaitForFinish) 
{ 
    ProcessStartInfo UnzipDiskImage = new ProcessStartInfo("7z.exe"); 
    StringBuilder str = new StringBuilder(); 
    str.Append("e "); 
    str.Append(pathToDiskImage); 
    str.Append(" -o"); 
    str.Append(extractPath); 
    str.Append(" * -r"); 
    UnzipDiskImage.Arguments = str.ToString(); 
    UnzipDiskImage.WindowStyle = ProcessWindowStyle.Hidden; 
    Process process = Process.Start(UnzipDiskImage); 
    if(WaitForFinish == true) 
    { 
     process.WaitForExit(); //My app had to wait for the extract to finish 
    } 
}