I am actually trying to extract a Fat Disk Image with DiskUtils but I am not getting the correct file names...
I get "\TURNER~3\TOPPER~1.P~1" in place of "\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
}
}
This is because DiscUtils does not support LFN [Long File Names]...
So I am looking for a perfect library to extract these files befor i try to make one myself...
Is there any way I can Extract it [maybe by DiscUtils] without FileName Errors...
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.
Here is some modifications that you can add to DiscUtils
to support FAT LFN
s:
First, make these changes to the Fat\Directory.cs
file, like this (you need to add the _lfns
variable, the GetLfnChunk
function, and modify the existing LoadEntries
function to add the lines marked with //+++
below):
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; //+++
}
}
}
Second, add these two public functions to the Fat\FatFileSystem.cs
file. They will be the new APIs to query on LFNs:
/// <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;
}
And that's it. Now, youll be able to dump a whole FAT disk recursively like this, for example:
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));
}
}
Use at your own risks! :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With