{"id":288,"date":"2008-06-16T23:22:17","date_gmt":"2008-06-16T23:22:17","guid":{"rendered":"https:\/\/driverentry.com.br\/en\/2008\/06\/16\/using-the-registry-part-1\/"},"modified":"2026-07-27T20:41:59","modified_gmt":"2026-07-27T20:41:59","slug":"using-the-registry-part-1","status":"publish","type":"post","link":"https:\/\/driverentry.com.br\/en\/2008\/06\/16\/using-the-registry-part-1\/","title":{"rendered":"Using the Registry (Part 1)"},"content":{"rendered":"<div style=\"text-align: right;\"><a href=\"https:\/\/driverentry.com.br\/2008\/06\/16\/utilizando-o-registry-parte-1\/\"><img loading=\"lazy\" decoding=\"async\" title=\"Em Portugu\u00eas\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/br.gif\" alt=\"\" width=\"21\" height=\"19\" \/><\/a><\/div>\n<p><img decoding=\"async\" style=\"float: right; margin: 0px 10px;\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/Registry.png\" border=\"0\" alt=\"\" \/><\/p>\n<p>In the last post, in response to a question from a reader, I mentioned a little about <a href=\"https:\/\/driverentry.com.br\/en\/2008\/06\/07\/creating-and-using-ioctls\/\">how to create and use new IOCTLs<\/a>. After all, the motto of this blog is <em>&#8220;To serve well to serve forever.&#8221;<\/em> Questions from readers are a great source of suggestions for new posts. I believe that like it is in any other specialty, driver development is a topic that can be broken up into many many parts. No wonder that the <a href=\"http:\/\/www.amazon.com\/Windows-2000-Device-Driver-Book\/dp\/0130204315\/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1213670808&amp;sr=1-1\">smallest book I know about driver development<\/a> has not less than four hundred pages. So, it&#8217;s good to know what the reader&#8217;s difficulties are to know what subject to post here. Feel free to send further suggestions or questions. Some time ago, I had received an email from Fabio Dias (Fortaleza, CE &#8211; BRA), who suggested a post on how to access the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Windows_Registry\">Registry<\/a> from a driver. Okay, let&#8217;s go.<\/p>\n<h3>HKEY_LOCAL_MACHINE is User-Mode stuff<\/h3>\n<p>Before going out there saying what APIs you should use to access the registry, let&#8217;s first take a look on how the registry is organized. I think the first step here is talk about opening a registry key. As in <em>User Mode<\/em>, we must have a string that informs the key path which we want to open, and thereby obtain a handle to it. Oops! Did I say I handle? Therefore, it is worth mentioning that the registry keys are also resources managed by the <strong>Object Manager<\/strong>. Registry keys are all stored under the <strong>&#8220;\\Registry&#8221; <\/strong>namespace. Thus, in <em>User Mode<\/em> we use HKEY_LOCAL_MACHINE name as one of the basic divisions of the registry, whereas in <em>Kernel Mode<\/em> we use <strong>&#8220;\\Registry\\Machine &#8220;<\/strong>. Similarly to HKEY_USERS we <strong>have  &#8220;\\Registry\\Users&#8221;<\/strong>. More details can be found <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff560909(VS.85).aspx\">here<\/a>.<\/p>\n<h3>Which is the CurrentControlSet?<\/h3>\n<p>The <em>DriverEntry <\/em>routine of any Windows NT driver receives two input parameters, one being a pointer to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff544174(VS.85).aspx\">DRIVER_OBJECT<\/a> structure, which represents the instance of our driver, and another parameter is a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff564879(VS.85).aspx\">UNICODE_STRING<\/a> containing the registry path, which indicates where our driver is registered. But how so? <strong>Can&#8217;t our driver know how it was registered in the registry?<\/strong> Here, in the reference is simple:<\/p>\n<div>\n<blockquote><p><em><strong>&#8220;The registry path string pointed to by RegistryPath is of the form \\Registry\\Machine\\System\\CurrentControlSet\\Services\\DriverName&#8221;<\/strong><\/em><\/p><\/blockquote>\n<p><em><strong> <\/strong><\/em>Okay, let&#8217;s take a ride on any driver and take a look at this using <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff561300(VS.85).aspx\">WinDbg<\/a>. Let me open a parenthesis here to say to any new reader of this blog that I&#8217;m using a virtual machine to run the tests with a sample driver, as it is explained in <a href=\"https:\/\/driverentry.com.br\/en\/2007\/05\/31\/step-into-kernel-vmwarewindbg\/\">this post<\/a>. This allows me to do Kernel Debugging not necessarily having to use two machines. To make the driver replacement easier for each modification I do, I am using WinDbg mapping drivers, as it is explained in <a href=\"https:\/\/driverentry.com.br\/en\/2007\/07\/16\/bug-on-my-boot-driver-now-what\/\">another post<\/a>. This feature allows WinDbg to always load a new driver version in the TARGET machine without the need of having to manually replace the driver in it. Close parenthesis.<\/p>\n<p>Even before the driver be  loaded, I have put a breakpoint on its <em>DriverEntry <\/em>routine.<strong> Oops! How can you put a breakpoint in a driver that has not been loaded?<\/strong> Oh, OK &#8230; You can do this using the <strong>bu <\/strong>command, as it is shown below. The breakpoints will be set whenever the driver will be loaded. In the following line, I list the breakpoints, <strong>just to&#8230;<\/strong> When the driver isloaded, its execution stops at my breakpoint and I use the <strong>!ustr <\/strong>extension, which shows the UNICODE_STRING contents, so that we can see the value of its second parameter.<\/p>\n<\/div>\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; color: red;\">kd> bu KernelReg!DriverEntry<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF; color: red;\">kd> bl<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"> 0 eu             0001 (0001) (KernelReg!DriverEntry)<\/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> g<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">KD: Accessing 'Z:\\Sources\\DriverEntry\\KernelReg\\objchk_w2k_x86\\i386\\KernelReg.sys'<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    (\\??\\C:\\WINDOWS\\system32\\drivers\\KernelReg.sys)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  File size 2K.<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">MmLoadSystemImage: Pulled \\??\\C:\\WINDOWS\\system32\\drivers\\KernelReg.sys from kd<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Breakpoint 0 hit<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">KernelReg!DriverEntry:<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">f8d394a0 8bff            mov     edi,edi<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA; color: red;\">kd> !ustr poi(pusRegistryPath)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">String(114,114) at 82302000: \\REGISTRY\\MACHINE\\SYSTEM\\<span style=\"color: red;\">ControlSet001<\/span>\\Services\\KernelReg<\/pre>\n<\/div>\n<p><strong>Mas n\u00e3o era pra ser CurrentControlSet?<\/strong> Na verdade o <em>CurrentControlSet<\/em> \u00e9 um link para um outro <em>ControlSet<\/em>. No caso observado acima, o <em>CurrentControlSet<\/em> est\u00e1 refletindo o <em>ControlSet001<\/em>, ou seja, as altera\u00e7\u00f5es feitas no <em>ControlSet001<\/em> s\u00e3o vistas no <em>CurrentControlSet<\/em> e vice-versa. O <em>CurrentControlSet<\/em> pode refletir qualquer outro <em>ControlSet<\/em>. Algumas regras determinam quando eles mudam, como em casos de mudan\u00e7as de configura\u00e7\u00f5es de sistema ou instala\u00e7\u00f5es de drivers. Para saber para onde o <em>CurrentControlSet<\/em> est\u00e1 apontando, d\u00ea uma olhada no valor <strong>Current<\/strong> que est\u00e1 na chave <em>&#8220;\\Registry\\Machine\\System\\Select&#8221;<\/em> como mostra a figura abaixo.<\/p>\n<p><strong>Shouldn&#8217;t It be CurrentControlSet?<\/strong> Actually <em>CurrentControlSet<\/em> is a link to another <em>ControlSet<\/em>. In the case noted above, <em>CurrentControlSet<\/em> is reflecting <em>ControlSet001<\/em>, i.e., changes in the <em>ControlSet001<\/em> are seen in <em>CurrentControlSet<\/em> and vice-versa. The <em>CurrentControlSet <\/em>can reflect any <em>ControlSet<\/em>. Some rules determine when they change, like in cases of system configuration changes or driver installation. To know where the <em>CurrentControlSet<\/em> is pointing to, take a look at the <strong>Current<\/strong> value, which is in <em>&#8220;\\Registry\\Machine\\System\\Select&#8221;<\/em> key, as it is shown below.<\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/RegCurrent.png\" alt=\"\" \/><\/div>\n<p>But that&#8217;s just for the sake of curiosity. When you use <em>CurrentControlSet<\/em> as part of the key path you wish to access, the <strong>Object Manager<\/strong> do the translation for you and everyone lives happily ever after.<\/p>\n<h3>Where is \\Registry\\Machine\\Software?<\/h3>\n<p>It may have already happened to some of you. You write a driver that should read a value in a certain <em>&#8220;\\Registry\\Machine\\Software&#8221;<\/em> key when the driver get loaded. While you do tests with the driver, which now has its <em>Start<\/em> set to Manual(3), everything works successfuly but, when you change the driver <em>Start<\/em> to <em>Boot(0)<\/em> or <em>System(1)<\/em>, it is not possible to open the same key, the driver receives <strong>STATUS_OBJECT_NAME_NOT_FOUND <\/strong>(0xc00000034).<\/p>\n<p><strong>What did you mean by &#8220;name not found&#8221;? It was here right now!<\/strong> What happened is that the SOFTWARE key is mounted later. Thus, during the system boot it does not exist yet. To access that key you have to wait a little, perhaps using <a href=\"https:\/\/driverentry.com.br\/en\/2007\/06\/24\/lets-start-again\/\">this post<\/a> idea. Then everything will work like fine.<\/p>\n<h3>Anything to say about HKEY_CURRENT_USER?<\/h3>\n<p>Well, let&#8217;s think. Who is the <em>Current User<\/em>? The user who is making a system call, right? Thus, according to tradition, you start thinking it&#8217;s easy and when you are logged in as Paul you manually start your driver. During the call to its <em>DriverEntry <\/em>routine, the driver read settings for the user logged in, which are actually stored in the Paulo&#8217;s HKEY_CURRENT_USER. Well, that&#8217;s right up here. Yeah, it&#8217;s all wrong. For Paul point of view, the settings are right there, but the <em>DriverEntry <\/em>routine is called in system context, which incidentally is not Paul.<\/p>\n<p>This is a problem faced even in <em>User Mode<\/em>, where services that run on system account try to open the HKEY_CURRENT_USER key. One thing we must bear in mind is that &#8220;The logged user&#8221; is not a simple system information. Try to imagine a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Terminal_service\">Terminal Service<\/a>, there may be multiple users logged in at the same time. Even when there is only one user logged into the system, threads can be executed in other user&#8217;s context or even in the system context. Drivers do not have its own context. Portions of the driver run in system context, others in arbitrary context. Depending on the driver type and its position within the device stack , it can receive calls in user&#8217;s context. That is the case of <a href=\"http:\/\/en.wikipedia.org\/wiki\/File_System\">File System<\/a> drivers for example.<\/p>\n<p><strong>Ah, OK! HKEY_CURRENT_USER will work!<\/strong> Er&#8230; How do I say that? No, it will not work. According to <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff560909(VS.85).aspx\">Microsoft&#8217;s reference<\/a>, there is no simple translation to HKEY_CURRENT_USER, but there are routines that provide simplifications. After all this chat about context, you will still have to access the HKEY_USERS key, or rather, <em>&#8220;\\Registry\\User&#8221;<\/em> in the format already familiar to <em>User Mode<\/em> programmers used with HKEY_USERS. An example is: <em>&#8220;\\Registry\\User\\S-1-5-21-73586283-1897051121-839522115-500&#8221;<\/em>. The equivalent for a system account is the  <em>&#8220;\\Registry\\User\\.DEFAULT&#8221;<\/em> key.<\/p>\n<h3>OK, ok, ok! An example please<\/h3>\n<p>Once again, I&#8217;m assuming you already know how to build and install a driver as it is explained in <a href=\"https:\/\/driverentry.com.br\/en\/2006\/09\/11\/getting-started\/\">this post<\/a>. The example code available for downloading at the end of this post can also be compiled on <a href=\"http:\/\/en.wikipedia.org\/wiki\/Visual_Studio\">Visual Studio<\/a> by using <a href=\"http:\/\/www.osronline.com\/article.cfm?article=43\">DDKBUILD<\/a>, as <a href=\"https:\/\/driverentry.com.br\/en\/2006\/11\/16\/kernel-visual-studio-2005\/\">this post<\/a> explains. In this example I will show how to read two registry values \u200b\u200bthat are in the key which it is shown below. To make the game more fun, when the driver get executed by the first time, it will create the key and its contained values\u200b\u200b when it realizes that it does not exist yet.<\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/RegParams.png\" alt=\"\" \/><\/div>\n<p>The values will be contained in a subkey of the one you received as a parameter in the <em>DriverEntry <\/em>routine. So our basic work on coding the <em>DriverEntry<\/em> routine is precisely to create the registry full path key that contains these values\u200b\u200b. With this UNICODE_STRING in hand, we will take it to the reading and writing in the registry routines. Below is the <em>DriverEntry <\/em>routine code. It does not contain anything special about the registry. As always, it&#8217;s worth a read on 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;\">***     DriverEntry<\/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;\">**      Our driver's entry point.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      Knife in the teeth and blood in the eyes.<\/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;\"><span style=\"color: blue;\">extern<\/span> <span style=\"color: #a31515;\">\"C\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">NTSTATUS<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">DriverEntry(__in PDRIVER_OBJECT  pDriverObject,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            __in PUNICODE_STRING pusRegistryPath)<\/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;\">    UNICODE_STRING  usParameters = RTL_CONSTANT_STRING(L<span style=\"color: #a31515;\">\"\\\\Parameters\"<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    UNICODE_STRING  usFullRegPath = {<span style=\"color: purple;\">0<\/span>, <span style=\"color: purple;\">0<\/span>, NULL};<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    PWCHAR          pwzBuffer = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    NTSTATUS        nts = STATUS_SUCCESS;<\/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 we receive as a parameter the registry path up to<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      our driver's key. Our parameters live in a<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      sub-key named \"Parameters\". Let's build the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      full path by appending the sub-key name to the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      registry path we received as a parameter.<\/span><\/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; Set the driver's unload callback routine.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            pDriverObject->DriverUnload = OnDriverUnload;<\/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; To do this append, we will need a buffer<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      large enough to store the original string<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      plus the size of the sub-key. Here we allocate<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      this buffer.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            pwzBuffer = (PWCHAR)ExAllocatePoolWithTag(PagedPool,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                      pusRegistryPath->Length +<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                      usParameters.Length,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                      _KRN_REG_TAG);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (pwzBuffer == NULL)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);<\/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; Now that we have the buffer, let's initialize the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      UNICODE_STRING structure for the string resulting from this append.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            RtlInitEmptyUnicodeString(&amp;usFullRegPath,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                      pwzBuffer,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                      pusRegistryPath->Length +<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                      usParameters.Length);<\/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; Copy the string received as a parameter<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            RtlCopyUnicodeString(&amp;usFullRegPath,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                 pusRegistryPath);<\/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; Concatenate the string \"\\Parameters\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            RtlAppendUnicodeStringToString(&amp;usFullRegPath,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                           &amp;usParameters);<\/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; Using the full path, try to load the parameters<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            nts = LoadParams(&amp;usFullRegPath);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/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; On failure, check whether the cause was the missing<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: green;\">\/\/      sub-key in the registry. This should happen when the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: green;\">\/\/      driver is run for the first time. But if the failure<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: green;\">\/\/      is a different one, then each to their own problems.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: blue;\">if<\/span> (nts != STATUS_OBJECT_NAME_NOT_FOUND)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                    ExRaiseStatus(nts);<\/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; Let's create the sub-key and write the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: green;\">\/\/      pre-defined values.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                nts = CreateParams(&amp;usFullRegPath);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                    ExRaiseStatus(nts);<\/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; Try to read the parameters again.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: green;\">\/\/      Okay, I know this is silly. After all, if I<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: green;\">\/\/      just created the parameters, why would I<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: green;\">\/\/      read them again? Well, just to illustrate.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                nts = LoadParams(&amp;usFullRegPath);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                    ExRaiseStatus(nts);<\/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;\">        <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; Cleaning up the mess.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (pwzBuffer)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                ExFreePool(pwzBuffer);<\/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!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        nts = GetExceptionCode();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">return<\/span> nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">}<\/pre>\n<\/div>\n<p>Let&#8217;s play with UNICODE_STRING a little more. Let&#8217;s look at the routine that writes the registry values\u200b\u200b. This routine does not offer anything much different than we&#8217;re used to seeing in <em>User Mode.<\/em> However, it&#8217;s like they say: <em>&#8220;One example is worthier than a thousand articles.&#8221;<\/em> Wow, that was terrible! I need to stop doing this. You must be thinking now: <em>&#8220;Wow! What I need to read to have a driver example.&#8221;<\/em><\/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;\">***     CreateParams<\/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;\">**      This routine is called when the key that contains<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      the parameters is not detected. It creates the key and the parameters<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      with pre-defined values.<\/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;\">NTSTATUS<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">CreateParams(__in    PUNICODE_STRING pusRegistryPath)<\/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;\">    HANDLE              hKey = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    NTSTATUS            nts = STATUS_SUCCESS;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    OBJECT_ATTRIBUTES   ObjAttributes;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    UNICODE_STRING      usStringParam = RTL_CONSTANT_STRING(L<span style=\"color: #a31515;\">\"String\"<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    UNICODE_STRING      usDWordParam = RTL_CONSTANT_STRING(L<span style=\"color: #a31515;\">\"DoubleWord\"<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    ULONG               ulParam = <span style=\"color: purple;\">0x12345678<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    WCHAR               wzParam[] = L<span style=\"color: #a31515;\">\"DriverEntry.com.br\"<\/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;\">__try<\/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: blue;\">__try<\/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; No secret here. It's all quick and easy.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            InitializeObjectAttributes(&amp;ObjAttributes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                       pusRegistryPath,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                       OBJ_CASE_INSENSITIVE,<\/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;\">                                       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; Create the new key and request<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      access to set values inside it.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            nts = ZwCreateKey(&amp;hKey,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                              KEY_SET_VALUE,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                              &amp;ObjAttributes,<\/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;\">                              REG_OPTION_NON_VOLATILE,<\/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;\">            <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                ExRaiseStatus(nts);<\/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; Set the numeric value<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            nts = ZwSetValueKey(hKey,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                &amp;usDWordParam,<\/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;\">                                REG_DWORD,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                &amp;ulParam,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                <span style=\"color: blue;\">sizeof<\/span>(ulParam));<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                ExRaiseStatus(nts);<\/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; Set the string value<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            nts = ZwSetValueKey(hKey,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                &amp;usStringParam,<\/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;\">                                REG_SZ,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                &amp;wzParam,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                <span style=\"color: blue;\">sizeof<\/span>(wzParam));<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                ExRaiseStatus(nts);<\/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;\">__finally<\/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; Close the handle of the newly created key<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (hKey)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                ZwClose(hKey);<\/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;\">    <span style=\"color: blue;\">__except<\/span>(EXCEPTION_EXECUTE_HANDLER)<\/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; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        nts = GetExceptionCode();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        ASSERT(FALSE);<\/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;\">return<\/span> nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">}<\/pre>\n<\/div>\n<p>Finally the funny part of this story. I believe that most of the fun is concentrated in the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff567069(VS.85).aspx\">ZwQueryValueKey<\/a> routine, which performs the reading of values \u200b\u200bin the registry.<\/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;\">NTSTATUS <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  ZwQueryValueKey(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    IN HANDLE  KeyHandle,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    IN PUNICODE_STRING  ValueName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    OUT PVOID  KeyValueInformation,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    IN ULONG  Length,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    OUT PULONG  ResultLength<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    );<\/pre>\n<\/div>\n<p>The point that differs from the API used in <em>User Mode<\/em> to do the same task is the third parameter <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff554218(VS.85).aspx\">KEY_VALUE_INFORMATION_CLASS<\/a>. An enum that tells what information we would get on a particular value in the registry. One of them asks only the name while another asks all the information and the latest all the partial information referring to the value.<\/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> _KEY_VALUE_INFORMATION_CLASS {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  KeyValueBasicInformation,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  KeyValueFullInformation,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  KeyValuePartialInformation<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">} KEY_VALUE_INFORMATION_CLASS;<\/pre>\n<\/div>\n<p>For each enum value, a different structure is returned. Always in a single block, the structure can bring a variety of information using <em>offsets <\/em>telling where to find the data within that single memory allocation.<\/p>\n<p>In the example, I used the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff554220(VS.85).aspx\">KeyValuePartialInformation<\/a>, which I imagine to be the most used. Once again my tip is to read the comments at the excerpt below.<\/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;\">***     LoadParams<\/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;\">**      This routine loads the global variables with the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      values retrieved from the registry.<\/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;\">NTSTATUS<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">LoadParams(__in PUNICODE_STRING pusRegistryPath)<\/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              hKey = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    NTSTATUS            nts = STATUS_SUCCESS;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    OBJECT_ATTRIBUTES   ObjAttributes;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    UNICODE_STRING      usStringParam = RTL_CONSTANT_STRING(L<span style=\"color: #a31515;\">\"String\"<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    UNICODE_STRING      usDWordParam = RTL_CONSTANT_STRING(L<span style=\"color: #a31515;\">\"DoubleWord\"<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    ULONG               ulBytes = <span style=\"color: purple;\">0<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    PWCHAR              pwzBuffer = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    PKEY_VALUE_PARTIAL_INFORMATION  pValueInfo = 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: blue;\">__try<\/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: blue;\">__try<\/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; Build the ObjectAttribute<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            InitializeObjectAttributes(&amp;ObjAttributes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                       pusRegistryPath,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                       OBJ_CASE_INSENSITIVE,<\/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;\">                                       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; Try to open the registry key<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            nts = ZwOpenKey(&amp;hKey,<\/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;\">                            &amp;ObjAttributes);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                ExRaiseStatus(nts);<\/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; Since the value has a fixed size, we can determine<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      the buffer size needed to read the value from the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      registry.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            ulBytes = <span style=\"color: blue;\">sizeof<\/span>(KEY_VALUE_PARTIAL_INFORMATION) + <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                      <span style=\"color: blue;\">sizeof<\/span>(ULONG) - <span style=\"color: blue;\">sizeof<\/span>(UCHAR);<\/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; Allocate the buffer for the read.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            pValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                ExAllocatePoolWithTag(PagedPool,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                      ulBytes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                      _KRN_REG_TAG);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (!pValueInfo)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);<\/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 we do the read.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            nts = ZwQueryValueKey(hKey,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  &amp;usDWordParam,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  KeyValuePartialInformation,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  pValueInfo,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  ulBytes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  &amp;ulBytes);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                ExRaiseStatus(nts);<\/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 make sure we read a DWORD<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            ASSERT(pValueInfo->Type == REG_DWORD);<\/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 load our global variable<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      with the value read from the registry.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            g_ulParam = *(PULONG)pValueInfo->Data;<\/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; Free the read buffer and zero the pointer.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      You may decide to allocate the read buffer<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      based on the largest value you need to read,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      and thus use the same buffer to read all<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      the smaller values. Here, once again, I am<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      redoing everything to demonstrate.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            ExFreePool(pValueInfo);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            pValueInfo = 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; Since the string can have any size in the registry,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      we will offer zero bytes of read buffer so that<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      the API tells us how much it needs for the whole buffer.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            nts = ZwQueryValueKey(hKey,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  &amp;usStringParam,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  KeyValuePartialInformation,<\/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;\">                                  <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  &amp;ulBytes);<\/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 must get one of these errors.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            ASSERT(nts == STATUS_BUFFER_OVERFLOW ||<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                   nts == STATUS_BUFFER_TOO_SMALL);<\/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 we allocate a buffer of the size<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      requested by the API.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            pValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                ExAllocatePoolWithTag(PagedPool,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                      ulBytes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                      _KRN_REG_TAG);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (!pValueInfo)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);<\/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; Now we will do the read again, but this time<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      offering a buffer of a decent size.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            nts = ZwQueryValueKey(hKey,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  &amp;usStringParam,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  KeyValuePartialInformation,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  pValueInfo,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  ulBytes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  &amp;ulBytes);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                ExRaiseStatus(nts);<\/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 must have read a string.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            ASSERT(pValueInfo->Type == REG_SZ);<\/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; Now let's allocate the buffer that will be used to hold<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/     the string read from the registry. So we can discard the buffer<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/     used by the read. The DataLength field brings the size of the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/     unicode string with the zero terminator. Note that this structure<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/     does not bring a UNICODE_STRING, but a WCHAR array.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            pwzBuffer = (PWCHAR)ExAllocatePoolWithTag(PagedPool,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                      pValueInfo->DataLength,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                      _KRN_REG_TAG);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (!pwzBuffer)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);<\/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; After some time programming, you get quick with some<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      things. I bet someone, and that includes myself, will one day<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      Copy-Paste this function to use somewhere else. Here,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      anticipating that the registry read may happen several times,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      and so, if there is an allocation from a previous read, we will<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      deallocate it.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (g_usParam.Length)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                RtlFreeUnicodeString(&amp;g_usParam);<\/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; Initialize the global string with the buffer we just allocated.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      Even though we set a buffer for this UNICODE_STRING, it is<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      still empty (Length=0)<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            RtlInitEmptyUnicodeString(&amp;g_usParam,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                      pwzBuffer,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                      (USHORT)pValueInfo->DataLength);<\/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 we append the WCSTR (zero-terminated WCHAR array), read<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      from the registry into our empty buffer. This is similar to a copy,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      but with an incredible advantage: not using wcslen().<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      Never mind, it's purist paranoia. So we leave it to the API to<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      determine the Length and MaximumLength of the UNICODE_STRING. Remember<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      that the zero terminator is not counted as part of the UNICODE_STRING.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            RtlAppendUnicodeToString(&amp;g_usParam,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                     (PCWSTR)pValueInfo->Data);<\/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;\">__finally<\/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; General cleanup<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (pValueInfo)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                ExFreePool(pValueInfo);<\/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> (hKey)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                ZwClose(hKey);<\/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! I did it again.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        nts = GetExceptionCode();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        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;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">return<\/span> nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">}<\/pre>\n<\/div>\n<p>Phew! What a big code! In this first part of the issue I have used the APIs that most closely resemble the <em>User Mode <\/em>ones. In the next post I will bring a different way of doing the same thing we did here.<\/p>\n<p>I hope I could help.<\/p>\n<p>CYA&#8230;<\/p>\n<p class=\"download\"><a href=\"http:\/\/www.driverentry.com.br\/samples\/KernelReg.zip\">KernelReg.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last post, in response to a question from a reader, I mentioned a little about how to create and use new IOCTLs. After all, the motto of this blog is &#8220;To serve well to serve forever.&#8221; Questions from readers are a great source of suggestions for new posts. I believe that like it [&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-288","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/288","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=288"}],"version-history":[{"count":6,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/288\/revisions"}],"predecessor-version":[{"id":294,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/288\/revisions\/294"}],"wp:attachment":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/media?parent=288"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/categories?post=288"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/tags?post=288"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}