{"id":467,"date":"2010-06-26T12:13:58","date_gmt":"2010-06-26T12:13:58","guid":{"rendered":"https:\/\/driverentry.com.br\/en\/2010\/06\/26\/mapping-files-into-memory\/"},"modified":"2026-07-31T19:12:02","modified_gmt":"2026-07-31T19:12:02","slug":"mapping-files-into-memory","status":"publish","type":"post","link":"https:\/\/driverentry.com.br\/en\/2010\/06\/26\/mapping-files-into-memory\/","title":{"rendered":"Mapping Files into Memory"},"content":{"rendered":"<div style=\"text-align: right;\"><a href=\"https:\/\/driverentry.com.br\/2010\/06\/26\/mapeando-arquivos-em-memoria\/\"><img loading=\"lazy\" decoding=\"async\" title=\"Em Portugues\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/br.gif\" alt=\"\" width=\"21\" height=\"19\" \/><\/a><\/div>\n<p>After illustrating some of the <strong>Memory Manager<\/strong>&#8216;s characteristics as a service provider to the <strong>Cache Manager<\/strong> in the <a href=\"https:\/\/driverentry.com.br\/en\/2010\/06\/09\/can-a-lost-pointer-in-the-kernel-corrupt-files\/\">previous post<\/a>, today I will demonstrate that mere <em>User-Mode<\/em> applications can also use such services. By mapping files into memory the application gains a range of virtual addresses that contains the file&#8217;s content. Access to the file&#8217;s content is done simply by dereferencing a pointer, without the need to call the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa365467(VS.85).aspx\">ReadFile()<\/a> or <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa365747(VS.85).aspx\">WriteFile()<\/a> functions.<\/p>\n<p>Want a need for this? Imagine that your application needs to search for a certain string in a file, let&#8217;s say &#8220;DriverEntry&#8221;. In a <em>&#8220;rice and beans&#8221;<\/em> development, the file handle is obtained through the call to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363858(VS.85).aspx\">CreateFile()<\/a> function, and a buffer receives the partial content of the file, let&#8217;s suppose 200 bytes. A simple search function from the API could perform such a search in the buffer.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" style=\"padding: 5px;\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/StrStr1.png\" alt=\"\" width=\"519\" height=\"132\" \/><\/p>\n<p>This solution would be perfect if there were no possibility of the searched word falling at the edges of the buffer, as illustrated below.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"padding: 5px;\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/StrStr2.png\" alt=\"\" width=\"527\" height=\"134\" \/><\/p>\n<p>A smarter algorithm would have to be used to identify the prefix and continue the search on the next read of the file.<\/p>\n<p>This is just a simple example, but it clearly illustrates one of the advantages of mapping files. If there were a simple function that received the path of a file and returned to us a pointer to its content, the search would be quite simple.<\/p>\n<p>Files mapped into memory can also make writing to their content easier. By writing to the pointer received from such a mapping, the Memory Manager will take charge of doing the necessary I\/O so that this new content reaches the disk.<\/p>\n<h3>A simple mapping function<\/h3>\n<p>Here I will exemplify the use of the routines that map a file into memory. The comments follow in the explanation.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     MapFileToMemory<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      Routine that receives the path of a file that will be<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      mapped into memory for reading. An address is<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      returned to the calling routine as well as the size<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      of the file.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">DWORD MapFileToMemory(LPCTSTR   tzFileName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                      LPVOID*   ppMemory,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                      LPDWORD   pdwSize)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    HANDLE  hFile = NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            hMapping = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    DWORD   dwError = ERROR_SUCCESS;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">__try<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">__try<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Zeroes output variables.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            *pdwSize = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            *ppMemory = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Here we open the file to be mapped<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            hFile = CreateFile(tzFileName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                               GENERIC_READ,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               FILE_SHARE_READ | FILE_SHARE_DELETE,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                               NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               OPEN_EXISTING,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                               FILE_ATTRIBUTE_NORMAL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               NULL);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; We check whether the file was opened; if not,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      the boogeyman comes and takes us away.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (hFile == INVALID_HANDLE_VALUE)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                RaiseException(GetLastError(),<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                               <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               NULL);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; Although the file size is not necessary<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      in this function, let's take advantage of having the file's<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      handle in hand to obtain this information for<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      the calling routine, which will need it.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            *pdwSize = GetFileSize(hFile,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                   NULL);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Here we create a mapping of the file.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      In kernel it would be the equivalent of creating a<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      section of the file.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            hMapping = CreateFileMapping(hFile,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                         NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                         PAGE_READONLY,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                         <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                         <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                         NULL);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Preventing the boogeyman.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (!hMapping)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                RaiseException(GetLastError(),<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                               <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               NULL);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; Here the mapping is actually done and we get the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      range of addresses that will contain the content<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      of the file.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            *ppMemory = MapViewOfFile(hMapping,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                      FILE_MAP_READ,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                      <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                      <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                      <span style=\"color: purple;\">0<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; The same boogeyman trick I already mentioned.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (!*ppMemory)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                RaiseException(GetLastError(),<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                               <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                               NULL);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: blue;\">__finally<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; Here is where we will do all the cleanup,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      closing the handles that were opened.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (hFile)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                CloseHandle(hFile);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (hMapping)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                CloseHandle(hMapping);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">__except<\/span>(EXCEPTION_EXECUTE_HANDLER)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Oops! Something did not go as rehearsed.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      Find someone to blame and pretend it is not your problem.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        dwError = GetExceptionCode();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">return<\/span> dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">}<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<\/div>\n<p>This example is really quite simple, but feel free to add parameters that make this function more flexible and complex.<\/p>\n<blockquote>\n<p>&#8220;Fernando, even if the file was mapped successfully, you close the file handle and the mapping handle. Shouldn&#8217;t that release the references this program has to the file?&#8221;<\/p>\n<\/blockquote>\n<p>Actually, after we create the file mapping using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa366537(VS.85).aspx\">CreateFileMapping()<\/a> routine, which receives the file handle, an extra reference has already been made to the file, and so we could already close its handle if we wanted to. The same happens with the call to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa366761(VS.85).aspx\">MapViewOfFile()<\/a> routine, which receives the mapping handle, and which in turn has an indirect reference to the mapped file. In other words, once everything is mapped we can close all the handles and let the indirect references take care of it.<\/p>\n<p>In the next source code we will see a simple example of using this function.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     _tmain<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      Simple use of the file-mapping function.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      Just so nobody says I did not do every little bit...<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">int<\/span> _tmain(<span style=\"color: blue;\">int<\/span> argc, _TCHAR* argv[])<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    PBYTE   pBuffer;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    DWORD   dwError, dwSize, i;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Passes the file name and obtains the pointer<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      with its content mapped. Just like that...<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    dwError = MapFileToMemory(_T(<span style=\"color: #a31515;\">\"C:\\\\Temp\\\\Test.txt\"<\/span>),<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                              (LPVOID*)&amp;pBuffer,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                              &amp;dwSize);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Testing for errors never hurts.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">if<\/span> (dwError == ERROR_SUCCESS)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Moments of suspense before touching the address.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        printf(<span style=\"color: #a31515;\">\"Hit any key to access the buffer at 0x%p...\\n\"<\/span>, pBuffer);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        _getch();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Prints each character stored in the file.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      \"Look, Mom! No ReadFile()!\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">for<\/span> (i=<span style=\"color: purple;\">0<\/span>; i<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            printf(<span style=\"color: #a31515;\">\"%c\"<\/span>, pBuffer[i]);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Here the mapping is undone.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        UnmapViewOfFile(pBuffer);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">return<\/span> dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">}<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<\/div>\n<p>At the end of this example we can observe the call to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa366882(VS.85).aspx\">UnmapViewOfFile()<\/a> routine, which simply receives the base pointer of the file mapping. With this call, all internal references are undone and the file is finally closed.<\/p>\n<h3>Testing the toy<\/h3>\n<p>So that we can run a silly test, create a text file using Notepad.exe.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"padding: 5px;\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/TextFileToMap.png\" alt=\"\" width=\"621\" height=\"219\" \/><\/p>\n<p>Running the test application we have the output as illustrated below.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"padding: 5px;\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/MapFileOutput2.png\" alt=\"\" width=\"684\" height=\"225\" \/><\/p>\n<h3>Now in the replay slow motion<\/h3>\n<p>With <a href=\"http:\/\/www.microsoft.com\/whdc\/devtools\/debugging\/default.mspx\">WinDbg<\/a> we can observe the exact moment when the application accesses the range of addresses referring to the file&#8217;s content. To do this we will place a breakpoint on the file-read routine of the <strong>Ntfs.sys<\/strong> driver; this way we will be able to see the Memory Manager&#8217;s request being served. For this to happen, the text file cannot be in the system cache, so if you have already run the test application at least once, you will have to restart the system.<\/p>\n<p>If you have not used WinDbg yet and do not know how to connect it to the system, then read <a href=\"https:\/\/driverentry.com.br\/en\/2006\/12\/01\/step-into-kernel-serial\/\">this post<\/a> for a quick start. After connecting WinDbg to the system Kernel, go to the directory where the test application is and run it, but do not press any key yet, leaving it stopped as shown below:<\/p>\n<p style=\"text-align: center;\"><img decoding=\"async\" class=\"aligncenter\" style=\"padding: 5px;\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/MapFileOutput1.png\" alt=\"\" \/><\/p>\n<p>After that, press Ctrl+Break in WinDbg so that you gain control over the debugged system, which at this moment will remain frozen.<\/p>\n<p>To place that breakpoint on the file-read routine of Ntfs.sys, we will need to know where this routine is within the driver. We can obtain this information using WinDbg&#8217;s <strong>!drvobj<\/strong> extension as shown below.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; !drvobj \\FileSystem\\Ntfs 2<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Driver object (843fd650) is for:<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"> \\FileSystem\\Ntfs<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">DriverEntry:   828f5b75    Ntfs!GsDriverEntry<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">DriverStartIo: 00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">DriverUnload:  00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">AddDevice:     00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Dispatch routines:<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[00] IRP_MJ_CREATE                      8289400a    Ntfs!NtfsFsdCreate<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[01] IRP_MJ_CREATE_NAMED_PIPE           8165a013    nt!IopInvalidDeviceRequest<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[02] IRP_MJ_CLOSE                       82896fcf    Ntfs!NtfsFsdClose<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: #ff0000;\">[03] IRP_MJ_READ                        82818514    Ntfs!NtfsFsdRead<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[04] IRP_MJ_WRITE                       82815638    Ntfs!NtfsFsdWrite<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[05] IRP_MJ_QUERY_INFORMATION           82895a88    Ntfs!NtfsFsdDispatchWait<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[06] IRP_MJ_SET_INFORMATION             8281e950    Ntfs!NtfsFsdSetInformation<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[07] IRP_MJ_QUERY_EA                    82895a88    Ntfs!NtfsFsdDispatchWait<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[08] IRP_MJ_SET_EA                      82895a88    Ntfs!NtfsFsdDispatchWait<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[09] IRP_MJ_FLUSH_BUFFERS               82884349    Ntfs!NtfsFsdFlushBuffers<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[0a] IRP_MJ_QUERY_VOLUME_INFORMATION    828b5fc6    Ntfs!NtfsFsdDispatch<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[0b] IRP_MJ_SET_VOLUME_INFORMATION      828b5fc6    Ntfs!NtfsFsdDispatch<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[0c] IRP_MJ_DIRECTORY_CONTROL           828b5d41    Ntfs!NtfsFsdDirectoryControl<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[0d] IRP_MJ_FILE_SYSTEM_CONTROL         8289970e    Ntfs!NtfsFsdFileSystemControl<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[0e] IRP_MJ_DEVICE_CONTROL              82879466    Ntfs!NtfsFsdDeviceControl<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     8165a013    nt!IopInvalidDeviceRequest<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[10] IRP_MJ_SHUTDOWN                    8282b36b    Ntfs!NtfsFsdShutdown<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[11] IRP_MJ_LOCK_CONTROL                82823b7a    Ntfs!NtfsFsdLockControl<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[12] IRP_MJ_CLEANUP                     828a1d42    Ntfs!NtfsFsdCleanup<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[13] IRP_MJ_CREATE_MAILSLOT             8165a013    nt!IopInvalidDeviceRequest<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[14] IRP_MJ_QUERY_SECURITY              828b5fc6    Ntfs!NtfsFsdDispatch<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[15] IRP_MJ_SET_SECURITY                828b5fc6    Ntfs!NtfsFsdDispatch<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[16] IRP_MJ_POWER                       8165a013    nt!IopInvalidDeviceRequest<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[17] IRP_MJ_SYSTEM_CONTROL              8165a013    nt!IopInvalidDeviceRequest<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[18] IRP_MJ_DEVICE_CHANGE               8165a013    nt!IopInvalidDeviceRequest<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[19] IRP_MJ_QUERY_QUOTA                 82895a88    Ntfs!NtfsFsdDispatchWait<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">[1a] IRP_MJ_SET_QUOTA                   82895a88    Ntfs!NtfsFsdDispatchWait<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[1b] IRP_MJ_PNP                         8286137b    Ntfs!NtfsFsdPnp<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Fast I\/O routines:<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">FastIoCheckIfPossible                   8288187b    Ntfs!NtfsFastIoCheckIfPossible<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">FastIoRead                              82880c38    Ntfs!NtfsCopyReadA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">FastIoWrite                             82881f53    Ntfs!NtfsCopyWriteA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">FastIoQueryBasicInfo                    82888c3a    Ntfs!NtfsFastQueryBasicInfo<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">FastIoQueryStandardInfo                 82888aa6    Ntfs!NtfsFastQueryStdInfo<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">FastIoLock                              8287bf41    Ntfs!NtfsFastLock<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">FastIoUnlockSingle                      8287bd75    Ntfs!NtfsFastUnlockSingle<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">FastIoUnlockAll                         828cd7b3    Ntfs!NtfsFastUnlockAll<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">FastIoUnlockAllByKey                    828cd958    Ntfs!NtfsFastUnlockAllByKey<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">ReleaseFileForNtCreateSection           8281e904    Ntfs!NtfsReleaseForCreateSection<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">FastIoQueryNetworkOpenInfo              8287ad84    Ntfs!NtfsFastQueryNetworkOpenInfo<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">AcquireForModWrite                      8280c892    Ntfs!NtfsAcquireFileForModWrite<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">MdlRead                                 828cd0d8    Ntfs!NtfsMdlReadA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">MdlReadComplete                         81650af6    nt!FsRtlMdlReadCompleteDev<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">PrepareMdlWrite                         828cd31f    Ntfs!NtfsPrepareMdlWriteA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">MdlWriteComplete                        817f5a9a    nt!FsRtlMdlWriteCompleteDev<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">FastIoQueryOpen                         82874d03    Ntfs!NtfsNetworkOpenCreate<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">AcquireForCcFlush                       8281ab35    Ntfs!NtfsAcquireFileForCcFlush<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">ReleaseForCcFlush                       8281aa9c    Ntfs!NtfsReleaseFileForCcFlush<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<\/div>\n<p>As you must be imagining, the Ntfs read routine is used very frequently, which would make this breakpoint stop many times without the slightest relation to our test. To limit the breakpoint&#8217;s scope, we will make it apply only to the thread that will make the request we are waiting for.<\/p>\n<p>As I already explained in the <a href=\"https:\/\/driverentry.com.br\/en\/2010\/06\/09\/can-a-lost-pointer-in-the-kernel-corrupt-files\/\">previous post<\/a>, when the memory address is obtained, the file has not yet been read. When the application dereferences this pointer looking for the data, a <em>page fault<\/em> will be generated and the Memory Manager will take control over the thread by means of a system <em>trap<\/em>. This is the thread that will be used to perform the read of the file that will supply the memory page at the Memory Manager&#8217;s request. This is the reason why our test program waits for a key to be pressed before accessing the buffer. This gives us the opportunity to obtain the identification of the thread that is waiting for that event.<\/p>\n<p>We use the <strong>!process<\/strong> extension to locate our test program, and it will also list its threads, which in our case is a single one.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; !process 0 2 MapFile.exe<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">PROCESS 84bf6d90  SessionId: 1  Cid: 0b60    Peb: 7ffdf000  ParentCid: 0b40<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    DirBase: 1f09b4c0  ObjectTable: 8e77ccd0  HandleCount:   5.<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    Image: MapFile.exe<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        THREAD <span style=\"color: #ff0000;\">84f6cb50<\/span>  Cid 0b60.0b64  Teb: 7ffde000 Win32Thread: 00000000 WAIT: (WrLpcReply) ...<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            84f6cd64  Semaphore Limit 0x1<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; bp \/1 \/t <span style=\"color: #ff0000;\">84f6cb50<\/span> Ntfs!NtfsFsdRead<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">kd&gt; g<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<\/div>\n<p>After placing the breakpoint, we can release the execution of the system and type something in the test application. This will make our breakpoint interrupt the system just as we intended. Looking at the call stack we have at the moment, we can evidence the execution of the trap that was generated by the test application. This <em>trap<\/em> is being served by the Memory Manager.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Breakpoint 0 hit<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Ntfs!NtfsFsdRead:<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">82818514 6a40<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; kb<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">ChildEBP <span style=\"color: #ff0000;\">RetAddr<\/span>  Args to Child<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">8f395b6c 816f00c3 84438020 <span style=\"color: #ff0000;\">84f40290<\/span> 84f40290 Ntfs!NtfsFsdRead<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">8f395b84 821a3ba7 84437730 84f40290 00000000 nt!IofCallDriver+0x63<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">8f395ba8 821a3d64 8f395bc8 84437730 00000000 fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x251<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">8f395be0 816f00c3 84437730 84f40290 00000000 fltmgr!FltpDispatch+0xc2<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">8f395bf8 8167bf2e 84f6cb50 8443a18c 8443a158 nt!IofCallDriver+0x63<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">8f395c14 816b8d51 00000043 84f6cb50 8443a198 nt!IoPageRead+0x172<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">8f395cd0 816db03f 00020000 90825810 00000000 nt!MiDispatchFault+0xd18<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">8f395d4c <span style=\"color: #ff0000;\">8168ebf4<\/span> 00000000 00020000 00000001 <span style=\"color: #ff0000;\">nt!MmAccessFault<\/span>+0x1fb7<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">8f395d4c 0018d972 00000000 00020000 00000001 <span style=\"color: #ff0000;\">nt!KiTrap0E<\/span>+0xdc<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">0015fbc0 0018ec36 00000001 00281a28 00281a78 MapFile!wmain+0x72<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">0015fc0c 0018eb0f 0015fc20 77554911 7ffdf000 MapFile!__tmainCRTStartup+0x116<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">0015fc14 77554911 7ffdf000 0015fc60 77ace4b6 MapFile!wmainCRTStartup+0xf<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">0015fc20 77ace4b6 7ffdf000 77a26775 00000000 kernel32!BaseThreadInitThunk+0xe<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">0015fc60 77ace489 0018b532 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x23<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">0015fc78 00000000 0018b532 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<\/div>\n<p>As we know the prototype that a dispatch routine must have, we know that the second parameter of the <em>NtfsFsdRead()<\/em> routine is the address of the <a href=\"https:\/\/driverentry.com.br\/en\/2007\/02\/12\/cool-but-what-is-an-irp\/\">IRP<\/a> that the driver received. Using the <strong>!irp<\/strong> extension we can obtain details about the IRP. This allows us to know the <em>FileObject<\/em> to which this request is destined.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; !irp <span style=\"color: #ff0000;\">84f40290<\/span> <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Irp is active with 8 stacks 8 is current (= 0x84f403fc)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"> Mdl=8443a1d8: No System Buffer: Thread 84f6cb50:  Irp stack trace.  <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">     cmd  flg cl Device   <span style=\"color: #ff0000;\">File<\/span>     Completion-Context<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"> [  0, 0]   0  0 00000000 00000000 00000000-00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            Args: 00000000 00000000 00000000 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"> [  0, 0]   0  0 00000000 00000000 00000000-00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            Args: 00000000 00000000 00000000 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"> [  0, 0]   0  0 00000000 00000000 00000000-00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            Args: 00000000 00000000 00000000 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"> [  0, 0]   0  0 00000000 00000000 00000000-00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            Args: 00000000 00000000 00000000 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"> [  0, 0]   0  0 00000000 00000000 00000000-00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            Args: 00000000 00000000 00000000 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"> [  0, 0]   0  0 00000000 00000000 00000000-00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            Args: 00000000 00000000 00000000 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"> [  0, 0]   0  0 00000000 00000000 00000000-00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            Args: 00000000 00000000 00000000 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&gt;[  3, 0]   0  0 84438020 <span style=\"color: #ff0000;\">84bd0028<\/span> 00000000-00000000    <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">           \\FileSystem\\Ntfs<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            Args: 00001000 00000000 00000000 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<\/div>\n<p>With the FileObject address in hand, the <strong>!fileobj<\/strong> extension will show us more details about this object. Thus we can verify that the file to be read is indeed our text file that was mapped.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; !fileobj <span style=\"color: #ff0000;\">84bd0028<\/span> <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: #ff0000;\">\\Temp\\Test.txt<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Device Object: 0x84439030   \\Driver\\volmgr<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Vpb: 0x84436e28<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Access: Read SharedRead SharedDelete <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Flags:  0x44042<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    Synchronous IO<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    Cache Supported<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    Cleanup Complete<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    Handle Created<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">FsContext: 0x92a4cd80    FsContext2: 0x92a4ced8<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">CurrentByteOffset: 0<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Cache Data:<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  Section Object Pointers: 84d24e74<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  Shared Cache Map: 00000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<\/div>\n<p>Knowing that we are in the context of the thread that made the access, we can take a little peek at the accessed address before the <em>page fault<\/em> is served. This address was shown in the test application&#8217;s output before the breakpoint interrupted the execution of the system.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; db <span style=\"color: #ff0000;\">0x00020000<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">00020000  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">00020010  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">00020020  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">00020030  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">00020040  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">00020050  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">00020060  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">00020070  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<\/div>\n<blockquote>\n<p>&#8220;Fernando, why do question marks appear? It&#8217;s fine that the file&#8217;s content has not yet been copied to the application&#8217;s buffer, but shouldn&#8217;t we see garbage or even zeros?&#8221;<\/p>\n<\/blockquote>\n<p>Look, that question of yours was really very good; I don&#8217;t think I myself could have thought of a better question. Actually the answer to this question is linked to that crude answer from the <a href=\"https:\/\/driverentry.com.br\/en\/2010\/06\/09\/can-a-lost-pointer-in-the-kernel-corrupt-files\/\">previous post<\/a>. What happens is that a range of addresses was reserved to contain the memory pages with the file&#8217;s content. Since no access has been made yet, this virtual address does not yet point to any physical memory page. Without this physical page one cannot determine its data. We can verify this using WinDbg&#8217;s <strong>!vtop<\/strong> extension, which translates virtual addresses to physical addresses.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; !vtop 0 <span style=\"color: #ff0000;\">0x00020000<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">X86VtoP: Virt 00020000, pagedir 1f09b4c0<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">X86VtoP: PAE PDPE 1f09b4c0 - 000000001876d801<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">X86VtoP: PAE PDE 1876d000 - 0000000018908867<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">X86VtoP: PAE PTE 18908100 - ffffffff00000420<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">X86VtoP: Virt ffffffff, pagedir 1f09b4c0<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">X86VtoP: PAE PDPE 1f09b4d8 - 00000000187b0801<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">X86VtoP: PAE PDE 187b0ff8 - 0000000000128063<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">X86VtoP: PAE PTE 128ff8 - 0000000000000000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">X86VtoP: PAE zero PTE<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Virtual address 20000 translation fails, error <span style=\"color: #ff0000;\">0x8007001E<\/span>.<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; !error <span style=\"color: #ff0000;\">0x8007001E<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Error code: (HRESULT) 0x8007001e (2147942430) - The system cannot read from the specified device.<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<\/div>\n<p>The attempt to translate this virtual address results in an error. Let&#8217;s try to do this translation again after the <em>page fault<\/em> is served. Let&#8217;s release the execution of the system up to the return address for the <em>MmAccessFault()<\/em> routine. This address was obtained in the thread&#8217;s call stack and was highlighted in the results of the <strong>kd<\/strong> command already illustrated above.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; ga <span style=\"color: #ff0000;\">8168ebf4<\/span> <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">nt!KiTrap0E+0xdc:<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">8168ebf4 85c0            test    eax,eax<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">kd&gt; !vtop 0 <span style=\"color: #ff0000;\">0x00020000<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">X86VtoP: Virt 00020000, pagedir 1f09b4c0<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">X86VtoP: PAE PDPE 1f09b4c0 - 000000001876d801<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">X86VtoP: PAE PDE 1876d000 - 0000000018908867<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">X86VtoP: PAE PTE 18908100 - 8000000018844025<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">X86VtoP: PAE Mapped phys 18844000<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Virtual address 20000 translates to physical address 18844000.<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<\/div>\n<p>Here the page fault has already been served and control will be returned to the application. At this point the Memory Manager performed the necessary tasks so that this virtual address could now be translated to a physical page. Repeating the same translation attempt that failed earlier, we will have the following output.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">kd&gt; db <span style=\"color: #ff0000;\">0x00020000<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">00020000  54 65 73 74 65 20 64 65-20 6d 61 70 65 61 6d 65  Teste de mapeame<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">00020010  6e 74 6f 20 64 65 20 61-72 71 75 69 76 6f 2e 2e  nto de arquivo..<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">00020020  2e 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">00020030  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">00020040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">00020050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">00020060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">00020070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................<\/pre>\n<\/div>\n<p>Releasing the execution of the system, the application will make the access to the buffer and we will have the same output shown earlier. It is worth remembering that to repeat this experiment, it is necessary to restart the system, because the text file&#8217;s content is now in the system <em>cache<\/em>. This means that the <em>page fault<\/em> will not occur again until this page is discarded by the Cache Manager. Such an event depends on many factors and may not happen until the machine shuts down.<\/p>\n<p>Anyway, this post, besides bringing a simple file-mapping function, also brings the same technical blah-blah-blah as always. I hope you liked it.<br \/>\n See you! \ud83d\ude09<\/p>\n<p class=\"download\"><a href=\"http:\/\/www.driverentry.com.br\/samples\/MapFile.zip\">MapFile.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>After illustrating some of the Memory Manager&#8216;s characteristics as a service provider to the Cache Manager in the previous post, today I will demonstrate that mere User-Mode applications can also use such services. By mapping files into memory the application gains a range of virtual addresses that contains the file&#8217;s content. Access to the file&#8217;s [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-467","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/comments?post=467"}],"version-history":[{"count":1,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/467\/revisions"}],"predecessor-version":[{"id":468,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/467\/revisions\/468"}],"wp:attachment":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/media?parent=467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/categories?post=467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/tags?post=467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}