{"id":408,"date":"2008-11-18T15:20:28","date_gmt":"2008-11-18T15:20:28","guid":{"rendered":"https:\/\/driverentry.com.br\/en\/2008\/11\/18\/managing-driver-paging\/"},"modified":"2026-07-31T00:01:40","modified_gmt":"2026-07-31T00:01:40","slug":"managing-driver-paging","status":"publish","type":"post","link":"https:\/\/driverentry.com.br\/en\/2008\/11\/18\/managing-driver-paging\/","title":{"rendered":"Managing driver paging"},"content":{"rendered":"<div style=\"text-align: right;\"><a href=\"https:\/\/driverentry.com.br\/2008\/11\/18\/gerenciando-paginacao-do-driver\/\"><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 talking so much about virtual memory and paging, I received a question that coincidentally has everything to do with the subject of the last posts. <span style=\"font-style: italic;\">&#8220;What are the <strong>pragma alloc_text<\/strong> that we see in the WDK examples for?&#8221;<\/span> (Thiago Cardoso, Recife-PE). This question must have already crossed the minds of many who have taken a look at the WDK examples. Since all the WDK examples I know use this pragma, it actually took a while for someone to ask about it. But anyway, let us get to what matters.<\/p>\n<p>As <a href=\"https:\/\/driverentry.com.br\/en\/2008\/09\/11\/a-pinch-of-virtual-memory\/\">we have already seen<\/a>, memory pages can be either in the RAM chips or on disk. We have also already seen that threads that are at a high execution priority cannot access data that is pageable. But how would we know which data is pageable or not?<\/p>\n<h3>Controlling Data Paging<\/h3>\n<p>When we allocate memory dynamically, we can choose whether the area of memory to be allocated will be pageable or not. The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms796846.aspx\">ExAllocatePool<\/a> function, and its sisters (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms796989.aspx\">ExAllocatePoolWithTag<\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms797113.aspx\">ExAllocatePoolWithQuota<\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms797114.aspx\">ExAllocatePoolWithQuotaTag<\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa490023.aspx\">ExAllocatePoolWithTagPriority<\/a>), receive a parameter of type POOL_TYPE that defines whether the memory to be allocated will be pageable or not.<\/p>\n<div style=\"font-family: Courier New; 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: blue;\">typedef<\/span> <span style=\"color: blue;\">enum<\/span> _POOL_TYPE {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF; color: red;\">  NonPagedPool,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA; color: red;\">  PagedPool,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  NonPagedPoolMustSucceed,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  DontUseThisType,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  NonPagedPoolCacheAligned,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  PagedPoolCacheAligned,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  NonPagedPoolCacheAlignedMustS<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">} POOL_TYPE;<\/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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">PVOID <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  ExAllocatePool(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    IN POOL_TYPE  PoolType,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    IN SIZE_T  NumberOfBytes<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    );<\/pre>\n<\/div>\n<p>You will have to manage which allocations will be accessed at different execution priorities. For example: A certain linked list is consulted only by functions that run at low IRQL, so all of its elements can be allocated in pageable memory (PagedPool). On the other hand, a linked list that is consulted by functions that run at high IRQLs must have its elements allocated in non-pageable memory (NonPagedPool).<\/p>\n<p><span style=\"font-weight: bold;\">Nice, Fernando, but not everything is allocated dynamically. What about static variables?<\/span><\/p>\n<p>By default, all global variables are non-pageable. This is bad if your driver has many global variables, which would require more non-pageable memory for your driver to be loaded, and, as has also already been seen, non-pageable memory should be conserved. Fortunately, we can define that a set of global variables can be pageable, as long as they are only accessed by threads at low IRQL.<\/p>\n<p>Within a module, be it an application, a DLL or even a driver, memory paging control is applied to the sections that compose them. For a group of variables to be defined in a pageable section, we can use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/thfhx4st.aspx\">data_seg pragma<\/a>. However, not every compiler allows us to do this. To know whether the compiler we are using supports the use of this pragma, we count on the WDK headers, which define the <span style=\"font-weight: bold;\">ALLOC_DATA_PRAGMA<\/span> symbol when the compiler offers support for this feature. This, obviously, has become less significant, since the advisable thing is to use the WDK&#8217;s own compiler, but it does not hurt to anticipate that your code might be compiled by some other compiler. See the example below that defines both non-pageable and pageable variables.<\/p>\n<div style=\"font-family: Courier New; 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;\">\/\/-f--&gt; These are variables defined in a non-pageable section<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">PDEVICE_OBJECT  g_pControlDeviceObj;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">PDRIVER_OBJECT  g_pDriverObj;<\/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 I check whether the compiler I am using<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      supports the use of #pragma data_seg.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      If so, I open the PAGEDATA section, which is a<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      pageable data section.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#ifdef<\/span> ALLOC_DATA_PRAGMA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">data_seg<\/span>(<span style=\"color: #a31515;\">\"PAGEDATA\"<\/span>)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#endif<\/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: green;\">\/\/-f--&gt; All the variables declared here will be pageable.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      So, only threads that run at a low<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      priority level will be able to access these variables<\/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: green;\">\/\/-f--&gt; We define a giant buffer. Good thing it is pageable<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">UCHAR   g_Buffer[<span style=\"color: purple;\">100000<\/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; Here we mark the end of the pageable section. The variables<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      defined after this #pragma will be non-pageable.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">#ifdef<\/span> ALLOC_DATA_PRAGMA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">data_seg<\/span>()<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">#endif<\/span><\/pre>\n<\/div>\n<h3>Controlling Code Paging<\/h3>\n<p>Memory is memory, whether to store data or code. We can also control where the functions you write will be defined. So, we can put all the functions that execute at low priority in pageable code sections. Here we will use the <span style=\"font-style: italic;\">pragma<\/span> that gave rise to Thiago&#8217;s question, the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/sw8ty6zf.aspx\">alloc_text pragma<\/a>.<\/p>\n<p>This <span style=\"font-style: italic;\">pragma<\/span> has two limitations. The first of them is that the <span style=\"font-style: italic;\">pragma<\/span> must be applied after the declaration of the function, but before its definition. The other is that this <span style=\"font-style: italic;\">pragma<\/span> is not applicable to C++ functions, that is, class methods or functions with overloads will not have this luxury of being pageable. If you are like me, who prefers to use the strong typing of C++ in drivers, even if you only write simple functions, you must use the <span style=\"font-weight: bold;\">extern &#8220;C&#8221;<\/span> modifier in the function declarations.<\/p>\n<p>This <span style=\"font-style: italic;\">pragma<\/span> is not necessarily supported by all compilers, and just like <span style=\"font-style: italic;\">data_seg<\/span>, the WDK headers define the <span style=\"font-weight: bold;\">ALLOC_PRAGMA<\/span> symbol to signal that the compiler used supports this feature. Here is one more example.<\/p>\n<div style=\"font-family: Courier New; 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;\">\/\/-f--&gt; Normally this declaration is made in a header<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      file. Note that if we are compiling in C++,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      we will have to use extern \"C\" to be able to define the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      section where the functions declared here will be defined.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#ifdef<\/span> __cplusplus<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">extern<\/span> <span style=\"color: #a31515;\">\"C\"<\/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;\">#endif<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Declares one<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    ULONG SumOne(IN ULONG ulParam);<\/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; Declares another<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    ULONG SumTwo(IN ULONG ulParam);<\/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;\">#ifdef<\/span> __cplusplus<\/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;\">#endif<\/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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/-f--&gt; The following part goes in the same module where the function is<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      defined, and must come before the function's definition.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      Note that here we test whether this pragma is supported, and<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      if so, each function must receive its alloc_text pragma<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">#ifdef<\/span> ALLOC_PRAGMA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(PAGE, SumOne);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(PAGE, SumTwo);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#endif<\/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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/-f--&gt; After that, we can define the functions normally<\/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;\">ULONG SumOne(IN ULONG ulParam);<\/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; SumOne function that was written by someone.<\/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; This comment is only funny in English.<\/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;\">\/\/      Function SumOne that has been written by someone<\/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;\">    PAGED_CODE();<\/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;\">return<\/span> ulParam + <span style=\"color: purple;\">1<\/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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">ULONG SumTwo(IN ULONG ulParam);<\/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; Damn function. (which is not funny at all)<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    PAGED_CODE();<\/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;\">return<\/span> SumOne(SomeOne(ulParam));<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">}<\/pre>\n<\/div>\n<p><span style=\"font-weight: bold;\">Fernando, what are these <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa489904.aspx\">PAGED_CODE<\/a> macros that you used in the example for?<\/span><\/p>\n<p>Well, here comes the little story. An uncomfortable thing is that problems with memory paging will only occur when the page you are accessing is on disk. This means that you can write a driver with a problem, test it, and if by &#8220;luck&#8221; the pages are all in RAM during the test, you will not see any problem. One of the things that helps a lot is this PAGED_CODE macro. In <span style=\"font-weight: bold;\">Checked Build<\/span>, this macro is translated into a function that will check whether the current priority is low enough to execute pageable code. If it is not, a <span style=\"font-style: italic;\">breakpoint<\/span> exception will be thrown. I hope you have the debugger attached to see that happen. Otherwise, do not worry, a lovely blue screen will appear and you will end up connecting the debugger sooner or later. When compiled in <span style=\"font-weight: bold;\">Free Build<\/span>, this macro is translated into nothing, avoiding a performance loss. In conclusion, this prevents you from calling a pageable function at high IRQL and everything working by &#8220;luck&#8221;.<\/p>\n<div style=\"font-family: Courier New; 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;\">...<\/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;\">#elif<\/span> DBG<\/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;\">#define<\/span> PAGED_CODE() {                                                       \\<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">if<\/span> (KeGetCurrentIrql() > APC_LEVEL) {                                    \\<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        KdPrint((<span style=\"color: #a31515;\">\"EX: Pageable code called at IRQL %d\\n\"<\/span>, KeGetCurrentIrql())); \\<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        NT_ASSERT(FALSE);                                                    \\<\/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;\">}<\/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;\">...<\/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;\">#else<\/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;\">#define<\/span> PAGED_CODE()        NOP_FUNCTION;<\/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;\">...<\/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;\">#endif<\/span><\/pre>\n<\/div>\n<p>An excellent way to catch code paging problems is to use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms792872.aspx\">Driver Verifier<\/a> with the <span style=\"font-weight: bold;\">Force IRQL Checking<\/span> option enabled. This option, besides checking whether you are calling the API functions at the correct priorities, also forces the paging of everything that is pageable in your driver every time the IRQL rises to DISPATCH_LEVEL or higher. This puts an end to that &#8220;luck&#8221; of using a pageable resource at high IRQL when the resource is already in RAM.<\/p>\n<h3>Discardable Section<\/h3>\n<p>Besides the <span style=\"font-weight: bold;\">PAGE<\/span> pageable code section we saw, another section is also seen very frequently in the WDK examples. The <span style=\"font-weight: bold;\">INIT<\/span> section is discarded when the call to your driver&#8217;s <span style=\"font-style: italic;\">DriverEntry<\/span> function returns to the system, and, if it is the case for your driver, after any reinitialization function has finished. If you do not know what a reinitialization function is, then take a pass through <a href=\"https:\/\/driverentry.com.br\/en\/2007\/06\/24\/lets-start-again\/\">this post<\/a>. So, if you have functions that are only used during the initialization of your driver (which in this case means: functions called by <span style=\"font-style: italic;\">DriverEntry<\/span>, or functions called by functions that were called by <span style=\"font-style: italic;\">DriverEntry<\/span>, or even functions called by functions that were called by functions&#8230; Ah! I think you got it), you can use the same procedure to define them in the INIT section in the same way as was done earlier. But it does not hurt to leave an example.<\/p>\n<div style=\"font-family: Courier New; 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;\">\/\/-f--&gt; The functions declared here will be removed from RAM when<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      the call to the DriverEntry function returns. Do not try to call them<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      after that, because they have already gone to the heaven of<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      initialization functions.<\/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;\">#ifdef<\/span> ALLOC_PRAGMA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(INIT, DriverEntry);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(INIT, FunctionCalledByDriverEntry);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(INIT, AnotherFunctionCalledByDriverEntry);<\/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;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(PAGE, SumOne);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(PAGE, SumTwo);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#endif<\/span><\/pre>\n<\/div>\n<p>This is especially useful in <span style=\"font-weight: bold;\">Legacy Drivers<\/span>, which perform many steps during initialization. Legacy drivers, besides searching for the hardware they are going to control, also need to do the association of the available resources (ports, interrupts, DMA channels, etc.), and this ends up consuming a significant amount of code. On the other hand, <span style=\"font-weight: bold;\">WDM<\/span> drivers receive everything all chewed up from the <span style=\"font-weight: bold;\">Plug-and-Play Manager<\/span>. The hardware was detected and the resource association was already negotiated. A beautiful thing of God!<\/p>\n<h3>Pageable or non-pageable, that is the question<\/h3>\n<p>Supposing that you have many functions that run at high IRQL, and that therefore must be in non-pageable memory, this would cause a large amount of non-pageable memory to be used to keep such functions, even if nobody is using the driver. We can also define our own sections and thus make them pageable or non-pageable when it is convenient for us. This would allow all those non-pageable functions to be pageable while nobody obtains a reference to our driver. This way, when we receive an <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms806162.aspx\">IRP_MJ_CREATE<\/a> or when we program the hardware to fire interrupts, we can tell the system that now we will need to make the section where such functions were defined non-pageable.<\/p>\n<p>First of all, we will have to create our own custom sections, and we will do this using the <span style=\"font-style: italic;\">alloc_text pragma<\/span> to define sections that must have their name in the format PAGExxxx, where xxxx is a unique name in your driver. See the little example, just to ease the conscience.<\/p>\n<div style=\"font-family: Courier New; 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;\">\/\/-f--&gt; The functions declared here will be defined in a section<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      that can be non-pageable when it is convenient for us.<\/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;\">#ifdef<\/span> ALLOC_PRAGMA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(PAGEABCD, FunctionOne);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(PAGEABCD, FunctionTwo);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#endif<\/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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/-f--&gt; The functions declared here will be defined in another<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      section that can be non-pageable. This way we can define<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      different groups of functions in different sections.<\/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;\">#ifdef<\/span> ALLOC_PRAGMA<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(PAGE1234, FunctionThree);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">#pragma<\/span> <span style=\"color: blue;\">alloc_text<\/span>(PAGE1234, FunctionFour);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#endif<\/span><\/pre>\n<\/div>\n<p>Now that we have defined which functions will be defined in that section, we can make it non-pageable only when such functions are used. For that we must use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms802002.aspx\">MmLockPagableCodeSection<\/a> function.<\/p>\n<div style=\"font-family: Courier New; 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;\">PVOID <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  MmLockPagableCodeSection(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    IN PVOID  AddressWithinSection<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    );<\/pre>\n<\/div>\n<p>To identify which section will be marked as non-pageable, we will have to pass an address that is inside the section. A name of a function defined in the section already solves the problem, but remember that all the functions inside the same section will be marked as non-pageable.<\/p>\n<p>The <span style=\"font-style: italic;\">MmLockPagableCodeSection<\/span> function returns to us an opaque address that can be used as a parameter for the call to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms801974.aspx\">MmUnlockPagableImageSection<\/a> function, which marks the section as pageable again. This function is normally called before the driver is unloaded. Following the line of our example, we could call this function upon receiving an <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms806166.aspx\">IRP_MJ_CLOSE<\/a>. The same address returned by <span style=\"font-style: italic;\">MmLockPagableCodeSection<\/span> can be used as a parameter for the calls to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms802008.aspx\">MmLockPagableSectionByHandle<\/a> function to make a section non-pageable again, which is much faster than the call to <span style=\"font-style: italic;\">MmLockPagableCodeSection<\/span>. So, we must call <span style=\"font-style: italic;\">MmLockPagableCodeSection<\/span> at least once to obtain the opaque pointer, and after that, we can call <span style=\"font-style: italic;\">MmLockPagableSectionByHandle<\/span> and <span style=\"font-style: italic;\">MmUnlockPagableImageSection<\/span>.<\/p>\n<div style=\"font-family: Courier New; 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;\">VOID <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  MmLockPagableSectionByHandle(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    IN PVOID  ImageSectionHandle<\/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<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">VOID <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  MmUnlockPagableImageSection(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    IN PVOID  ImageSectionHandle<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    );<\/pre>\n<\/div>\n<p>The same can be done in custom sections that define data, but we must use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms801971.aspx\">MmLockPagableDataSection<\/a> function to obtain the opaque pointer that identifies the section.<\/p>\n<h3>Can my function be pageable?<\/h3>\n<p><span style=\"font-weight: bold;\">Fernando, if my function is called at PASSIVE_LEVEL, then can it be pageable?<\/span><\/p>\n<p>It is not quite like that. Your function, even being called at PASSIVE_LEVEL, may contain intervals of code that need to be non-pageable. If you call functions that raise the IRQL, such as <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms801656.aspx\">KeAcquireSpinLock<\/a>, your function cannot be defined in a pageable section.<\/p>\n<p><span style=\"font-weight: bold;\">But Fernando, follow my reasoning. If the function was called and is executing at the moment, is it not obvious that the page it is contained in is in RAM?<\/span><\/p>\n<p>You may not believe it, but a function is composed of a chain of bytes that may be on page boundaries. This means that the beginning of your function may be at the end of a page, which in fact was paged to RAM when the call was made, but we do not know where a new page may begin. This new page may be on disk, and if it is accessed at high IRQL, the paging will cause a blue screen. Look at the code below to get an idea of what I am talking about, and do not forget to read the comments.<\/p>\n<div style=\"font-family: Courier New; 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;\">***     FunctionCalledAtPassiveLevel<\/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 is called at PASSIVE_LEVEL,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      but has an IRQL elevation during the call.<\/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;\">PLIST_ENTRY<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">FunctionCalledAtPassiveLevel(VOID)<\/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;\">    KIRQL       Irql;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    PLIST_ENTRY pEntry = 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;\">    PAGED_CODE();<\/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 our IRQL goes sky-high; if the code that<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      comes after this call is on the next memory page<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      that happens to be on disk, then (BOOM !!!)<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    KeAquireSpinLock(&amp;g_SpinLock, &amp;Irql);<\/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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt;    -------======= Page boundary =======-------<\/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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; The code here runs at DISPATCH_LEVEL, which<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      prevents this function from being defined in a<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      pageable section.<\/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: blue;\">if<\/span> (!IsListEmpty(&amp;g_NonPagedList))<\/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;\">        pEntry = RemoveHeadList(&amp;g_NonPagedList);<\/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<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; It is fine for you to access only non-pageable data,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      but the code you use for such access also needs<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      to be in non-pageable memory. After all, this code is<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      running at high IRQL and retrieving a page of<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      code from disk would result in horrible things.<\/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; We are back at PASSIVE_LEVEL<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    KeReleaseSpinLock(Irql);<\/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> pEntry;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">}<\/pre>\n<\/div>\n<p>If you have functions that are large, but that contain occasional intervals with IRQL elevation, then separate such intervals into isolated functions that can be defined in non-pageable sections, thus allowing you to define your large and complex function in a pageable section.<\/p>\n<p>Phew! I could still write a few more comments on this subject, but if I am already tired of writing, I can imagine how you are. The subject is dealt with in full detail in the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa489514.aspx\">reference<\/a>. But if you have any doubt about it, just send me an e-mail and hope that I know how to answer.<\/p>\n<p>See you!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After talking so much about virtual memory and paging, I received a question that coincidentally has everything to do with the subject of the last posts. &#8220;What are the pragma alloc_text that we see in the WDK examples for?&#8221; (Thiago Cardoso, Recife-PE). This question must have already crossed the minds of many who have taken [&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-408","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/408","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=408"}],"version-history":[{"count":1,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/408\/revisions"}],"predecessor-version":[{"id":409,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/408\/revisions\/409"}],"wp:attachment":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/media?parent=408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/categories?post=408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/tags?post=408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}