<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>[C#] Reading the Master File Table</title>
		<link>http://www.allegro.cc/forums/view/604162</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 02 Jun 2010 01:12:34 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Is there any way to gain access and parse the $MFT using only C# methods? I&#39;ve seen a couple of methods, including using PInvoke, or importing lots of DLLs, but they seem really confusing. I&#39;m hoping there&#39;s a better way to do that?</p><p>I need the full file/directory tree of all drives and I&#39;m just not going to parse the entire hard drive to get that <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CursedTyrant)</author>
		<pubDate>Wed, 26 May 2010 03:25:06 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You&#39;ll probably have to use PInvoke. It&#39;s not that bad though, and for standard Win32 API, pinvoke.net has prewritten bindings for pretty much everything.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kibiz0r)</author>
		<pubDate>Wed, 26 May 2010 04:28:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I highly doubt that sort of thing would be exposed via a .NET api. Using Invoke (platform invoke) with the relevant API is probably your best bet.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (BAF)</author>
		<pubDate>Wed, 26 May 2010 07:30:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Does (as in I can&#39;t be bothered to search in more depth) the WMI (<a href="http://en.wikipedia.org/wiki/Windows_Management_Instrumentation">http://en.wikipedia.org/wiki/Windows_Management_Instrumentation</a>) let you do this? I use it to interrogate processes and stuff and I bet it has file table capabilities.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Neil Walker)</author>
		<pubDate>Wed, 26 May 2010 18:24:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ve managed to write something like this, tough it&#39;s probably horribly, horribly <span class="cuss"><span>fuck</span></span>ed up. Can anyone take a look and tell me if and what I&#39;m doing wrong? Also, I want to know what should I do next <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /> That piece of code below is based on something I found on some forum:</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>Call the api function &lt;DeviceIoControl&gt; with the FSCTL_GET_RETRIEVAL_POINTERS ControlCode to find out, where the MFT is located on the volume ( the MFT can be fragmented ).</p><p>Create a volume-handle with the api function &lt;CreateFile&gt;.</p><p>Set a pointer to the mft-clusters on the volume. Call the api function &lt;SetFilePointerEx&gt; to do this. You can use the created volume-handle on this function call.</p><p>Read the clusters with the api function &lt;ReadFile&gt;.</p></div></div><p>

</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">public</span> <span class="k1">const</span> <span class="k1">int</span> FSCTL_GET_RETRIEVAL_POINTERS <span class="k3">=</span> <span class="n">0x00090073</span><span class="k2">;</span>
<span class="number">  2</span>        <span class="k1">public</span> <span class="k1">const</span> <span class="k1">int</span> FILE_CURRENT <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number">  3</span>
<span class="number">  4</span>        <span class="k2">[</span>DllImport<span class="k2">(</span><span class="s">"kernel32.dll"</span>, ExactSpelling <span class="k3">=</span> <span class="k1">true</span>, SetLastError <span class="k3">=</span> <span class="k1">true</span>, CharSet <span class="k3">=</span> CharSet.Auto<span class="k2">)</span><span class="k2">]</span>
<span class="number">  5</span>        <span class="k1">static</span> <span class="k1">extern</span> <span class="k1">bool</span> DeviceIoControl<span class="k2">(</span>IntPtr hDevice, uint dwIoControlCode,
<span class="number">  6</span>        IntPtr lpInBuffer, uint nInBufferSize,
<span class="number">  7</span>        IntPtr lpOutBuffer, uint nOutBufferSize,
<span class="number">  8</span>        out uint lpBytesReturned, IntPtr lpOverlapped<span class="k2">)</span><span class="k2">;</span>
<span class="number">  9</span>
<span class="number"> 10</span>        <span class="k2">[</span>DllImport<span class="k2">(</span><span class="s">"Kernel32.dll"</span>, SetLastError <span class="k3">=</span> <span class="k1">true</span>, CharSet <span class="k3">=</span> CharSet.Auto<span class="k2">)</span><span class="k2">]</span>
<span class="number"> 11</span>        <span class="k1">public</span> <span class="k1">static</span> <span class="k1">extern</span> IntPtr CreateFile<span class="k2">(</span>
<span class="number"> 12</span>        string fileName,
<span class="number"> 13</span>        <span class="k2">[</span>MarshalAs<span class="k2">(</span>UnmanagedType.U4<span class="k2">)</span><span class="k2">]</span> FileAccess fileAccess,
<span class="number"> 14</span>        <span class="k2">[</span>MarshalAs<span class="k2">(</span>UnmanagedType.U4<span class="k2">)</span><span class="k2">]</span> FileShare fileShare,
<span class="number"> 15</span>        IntPtr securityAttributes,
<span class="number"> 16</span>        <span class="k2">[</span>MarshalAs<span class="k2">(</span>UnmanagedType.U4<span class="k2">)</span><span class="k2">]</span> FileMode creationDisposition,
<span class="number"> 17</span>        <span class="k1">int</span> flags,
<span class="number"> 18</span>        IntPtr <span class="k1">template</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 19</span>
<span class="number"> 20</span>        <span class="k2">[</span>DllImport<span class="k2">(</span><span class="s">"kernel32.dll"</span><span class="k2">)</span><span class="k2">]</span>
<span class="number"> 21</span>        <span class="k1">static</span> <span class="k1">extern</span> <span class="k1">bool</span> SetFilePointerEx<span class="k2">(</span>IntPtr hFile, <span class="k1">long</span> liDistanceToMove,
<span class="number"> 22</span>        IntPtr lpNewFilePointer, uint dwMoveMethod<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 23</span>
<span class="number"> 24</span>        <span class="k2">[</span>DllImport<span class="k2">(</span><span class="s">"kernel32.dll"</span>, SetLastError <span class="k3">=</span> <span class="k1">true</span><span class="k2">)</span><span class="k2">]</span>
<span class="number"> 25</span>        <span class="k1">private</span> unsafe <span class="k1">static</span> <span class="k1">extern</span> <span class="k1">bool</span> ReadFile<span class="k2">(</span>
<span class="number"> 26</span>        IntPtr hFile,                        <span class="c">// handle to file</span>
<span class="number"> 27</span>        byte<span class="k2">[</span><span class="k2">]</span> lpBuffer,                <span class="c">// data buffer</span>
<span class="number"> 28</span>        <span class="k1">int</span> nNumberOfBytesToRead,        <span class="c">// number of bytes to read</span>
<span class="number"> 29</span>        ref <span class="k1">int</span> lpNumberOfBytesRead,    <span class="c">// number of bytes read</span>
<span class="number"> 30</span>        <span class="k1">int</span><span class="k3">*</span> ptr
<span class="number"> 31</span>        <span class="c">//</span>
<span class="number"> 32</span>        <span class="c">// ref OVERLAPPED lpOverlapped        // overlapped buffer</span>
<span class="number"> 33</span>        <span class="k2">)</span><span class="k2">;</span>
<span class="number"> 34</span>
<span class="number"> 35</span>        <span class="k1">public</span> <span class="k1">static</span> unsafe <span class="k1">void</span> GetMFT<span class="k2">(</span><span class="k2">)</span>
<span class="number"> 36</span>        <span class="k2">{</span>
<span class="number"> 37</span>            IntPtr inputBuffer <span class="k3">=</span> IntPtr.Zero<span class="k2">;</span>
<span class="number"> 38</span>            IntPtr outputBuffer <span class="k3">=</span> IntPtr.Zero<span class="k2">;</span>
<span class="number"> 39</span>
<span class="number"> 40</span>            uint lpBytesReturned <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 41</span>
<span class="number"> 42</span>            UInt64 n <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 43</span>            IntPtr ptr <span class="k3">=</span> <span class="k1">new</span> IntPtr<span class="k2">(</span><span class="k3">&amp;</span>n<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 44</span>
<span class="number"> 45</span>            IntPtr tmpHandle <span class="k3">=</span> CreateFile<span class="k2">(</span>@<span class="s">"\\\\.\\C:"</span>, FileAccess.Read, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, <span class="n">0</span>, IntPtr.Zero<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 46</span>            DeviceIoControl<span class="k2">(</span>tmpHandle, FSCTL_GET_RETRIEVAL_POINTERS, inputBuffer, <span class="k2">(</span>uint<span class="k2">)</span>Marshal.SizeOf<span class="k2">(</span>inputBuffer<span class="k2">)</span>, outputBuffer, <span class="k2">(</span>uint<span class="k2">)</span>Marshal.SizeOf<span class="k2">(</span>outputBuffer<span class="k2">)</span>, out lpBytesReturned, IntPtr.Zero<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 47</span>            SetFilePointerEx<span class="k2">(</span>tmpHandle, <span class="n">0</span>, ptr, FILE_CURRENT<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 48</span>            byte<span class="k2">[</span><span class="k2">]</span> data <span class="k3">=</span> doReadFile<span class="k2">(</span>ptr, <span class="k1">sizeof</span><span class="k2">(</span>IntPtr<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 49</span>        <span class="k2">}</span>
<span class="number"> 50</span>
<span class="number"> 51</span>        <span class="k1">public</span> <span class="k1">static</span> unsafe byte<span class="k2">[</span><span class="k2">]</span> doReadFile<span class="k2">(</span>IntPtr argHandle, <span class="k1">int</span> InputReportByteLength<span class="k2">)</span>
<span class="number"> 52</span>        <span class="k2">{</span>
<span class="number"> 53</span>            <span class="k1">int</span> BytesRead <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 54</span>            byte<span class="k2">[</span><span class="k2">]</span> BufBytes <span class="k3">=</span> <span class="k1">new</span> byte<span class="k2">[</span>InputReportByteLength<span class="k2">]</span><span class="k2">;</span>
<span class="number"> 55</span>            <span class="k1">if</span> <span class="k2">(</span>ReadFile<span class="k2">(</span>argHandle, BufBytes, InputReportByteLength, ref BytesRead, null<span class="k2">)</span><span class="k2">)</span>
<span class="number"> 56</span>            <span class="k2">{</span>
<span class="number"> 57</span>                byte<span class="k2">[</span><span class="k2">]</span> OutBytes <span class="k3">=</span> <span class="k1">new</span> byte<span class="k2">[</span>BytesRead<span class="k2">]</span><span class="k2">;</span>
<span class="number"> 58</span>                Array.Copy<span class="k2">(</span>BufBytes, OutBytes, BytesRead<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 59</span>                <span class="k1">return</span> OutBytes<span class="k2">;</span>
<span class="number"> 60</span>            <span class="k2">}</span>
<span class="number"> 61</span>            <span class="k1">else</span>
<span class="number"> 62</span>            <span class="k2">{</span>
<span class="number"> 63</span>                <span class="k1">return</span> null<span class="k2">;</span>
<span class="number"> 64</span>            <span class="k2">}</span>
<span class="number"> 65</span>        <span class="k2">}</span>
</div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CursedTyrant)</author>
		<pubDate>Fri, 28 May 2010 01:58:37 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Does it work? If not, what doesn&#39;t work? <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /> Personally, I&#39;ve never directly interfaced a C# application with anything non-.NET before.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Fri, 28 May 2010 03:15:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It&#39;s not really a problem with interfacing .NET with non-.NET stuff. It&#39;s mostly just the fact that I have no idea what the hell should I do. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /> There doesn&#39;t seem to be a clear documentation/paper/tutorial/book/whatever on how to read a directory tree from $MFT and I just don&#39;t know how to proceed.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CursedTyrant)</author>
		<pubDate>Fri, 28 May 2010 03:18:28 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>What are you trying to accomplish? There probably isn&#39;t clear documentation because this is quite an unusual task...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (BAF)</author>
		<pubDate>Fri, 28 May 2010 03:31:15 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I need the full directory &amp; file tree of each logical drive, and I don&#39;t want to parse directories/files just to get that (I&#39;ve tried, it&#39;s just too damn slow). Since $MFT contains records for every directory and file on a logical drive, I want to extract that data from there (it would be a lot faster).</p><p><b>EDIT:</b> So, does <b>anyone</b> know how to: a) read the MFT and b) iterate through and read all the MFT records?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CursedTyrant)</author>
		<pubDate>Wed, 02 Jun 2010 00:14:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I imagine there must already be existing code for this. GNU find can do it, albeit it&#39;s still quite slow for an entire file system (I think &quot;logical drive&quot; is irrelevant in UNIX&#39;s user land). The alternative is using an index, like GNU locate/updatedb, which is actually quite fast.</p><p>Oh, ... Windows? Accept defeat. You might try Cygwin, but it obviously depends on just what you&#39;re doing where. .NET probably means that GNU findutils won&#39;t work very well for you.</p><p>I still find it hilarious how easily my entire<span class="ref"><sup>[<a href="#">1</a>]</sup></span> Linux file system is indexed (and has been for years) compared to Windows. IIRC, Windows 7 only indexes user folders and the like (and even that is slow), making the Start Menu search feature nearly useless for a power user, and barely useful even for a regular user.</p><p>While I&#39;m ranting, I also find it infuriating that Windows <i>still</i> lacks a decent &quot;Home folder&quot; concept. It sort of exists (<tt>%USERPROFILE%</tt><span class="ref"><sup>[<a href="#">2</a>]</sup></span>, anyone?), but Windows Explorer doesn&#39;t list it as a quick jump, and indeed still uses fake paths when going to &quot;special&quot; folders, like &quot;Pictures&quot; AKA &quot;My Pictures&quot; (or should I say &quot;Libraries &gt; Pictures&quot;, <b>WTF?!</b>), making you have to click two or three times to get to root of the home folder.
</p><div class="ref-block"><h2>References</h2><ol><li>Well I think there are probably <i>some</i> excluded areas by default, but for <i>actual</i> good reasons.</li><li>13 keystrokes, if anyone is counting.</li></ol></div></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Wed, 02 Jun 2010 00:30:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m sure there&#39;s some code that does just that, but I searched and searched, and found nothing. I don&#39;t care if it&#39;s C++ (it&#39;s pretty much the only way to do this, and I can use pinvoke.net as reference for methods I&#39;d need), I just don&#39;t know how to do what I want. Like I said before, $MFT contains a record for every file and directory on the logical drive and thus, parsing it would be a hell of a lot faster (even if it&#39;s more than just a few MBs) than parsing every directory and file on the hard drive.</p><p>Any ideas?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CursedTyrant)</author>
		<pubDate>Wed, 02 Jun 2010 00:42:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;d recommend studying the API as if you were in C++, ignore pinvoke for the moment and figure out how you would do it using the plain API. Then move it to pinvoke.</p><p>And if all else fails, $MFT is an actual file on the filesystem, so you can open it and parse it yourself.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kibiz0r)</author>
		<pubDate>Wed, 02 Jun 2010 00:47:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/604162/867852#target">Kibiz0r</a> said:</div><div class="quote"><p>
And if all else fails, $MFT is an actual file on the filesystem, so you can open it and parse it yourself.
</p></div></div><p>
How is that even possible? <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /> I&#39;m thinking of chickens and eggs. <img src="http://www.allegro.cc/forums/smileys/lipsrsealed.gif" alt=":-X" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Wed, 02 Jun 2010 01:07:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/604162/867858#target">bamccaig</a> said:</div><div class="quote"><p>How is that even possible? <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /> I&#39;m thinking of chickens and eggs. <img src="http://www.allegro.cc/forums/smileys/lipsrsealed.gif" alt=":-X" /></p></div></div><p>Its most likely a virtual file, just a pointer to a section of disk, rather than a real file entry.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Wed, 02 Jun 2010 01:10:30 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>@CursedTyrant: Have you stumbled across <a href="http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/c1550294-d121-4511-ac32-31551497f64e#1f44bad6-0d65-40e0-83a0-d5936c657585">this</a> yet? He seems to claim to have done (and be doing) exactly what you want.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Wed, 02 Jun 2010 01:12:34 +0000</pubDate>
	</item>
</rss>
