<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog | Software Verify</title>
	<atom:link href="https://www.softwareverify.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.softwareverify.com/blog/</link>
	<description>Troubleshoot your software</description>
	<lastBuildDate>Fri, 27 Feb 2026 13:14:28 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Stop using booleans, they&#8217;re hurting your code</title>
		<link>https://www.softwareverify.com/blog/stop-using-booleans-theyre-hurting-your-code/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Fri, 27 Feb 2026 13:10:17 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12882</guid>

					<description><![CDATA[<p>At Software Verify we&#8217;ve started to phase out the use of booleans in our code. The use of booleans hinders readability and maintainability of the [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/stop-using-booleans-theyre-hurting-your-code/">Stop using booleans, they&#8217;re hurting your code</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>At Software Verify we&#8217;ve started to phase out the use of booleans in our code.</p>
<p>The use of booleans hinders readability and maintainability of the code.</p>
<p>The use of booleans also allow potential unwanted parameter reordering mistakes to occur.</p>
<p>Some bold claims. I will explain.</p>
<h2>Problem 1: Readability and maintainability</h2>
<p>If you saw this function call in your code what do you think it would do?</p>
<pre>    ok = attachExceptionTracerToRunningProcess(targetProcessId, TRUE, FALSE, _T("d:\\Exception Tracer"));
</pre>
<p>To find out we&#8217;d need to look at the function prototype, or the documentation. Most likely you&#8217;re is going to right click in Visual Studio and ask to see the function definition, or a tooltip is going to tell you what the argument names are. </p>
<p>Here&#8217;s the function definition:</p>
<pre>    int attachExceptionTracerToRunningProcess(const DWORD  processId,
                                              const bool   processBitDepth,
                                              const bool   singleStep,
                                              const TCHAR* dir);
</pre>
<p>To use this function you need to pass a process id, a directory path and two boolean values.</p>
<p>We can guess that passing <span style="font-family: 'courier new', courier, monospace;">TRUE</span> for <span style="font-family: 'courier new', courier, monospace;">singleStep</span> will start Exception Tracer in single stepping mode. But that&#8217;s implied, it&#8217;s not explicit.</p>
<p>But <span style="font-family: 'courier new', courier, monospace;">processBitDepth</span>, what does that do? You&#8217;ll need to read the documentation for that : <span style="font-family: 'courier new', courier, monospace;">FALSE</span> starts 32 bit Exception Tracer, and <span style="font-family: 'courier new', courier, monospace;">TRUE</span> starts 64 bit Exception Tracer.</p>
<p>Reading documentation is not a problem, but it doesn&#8217;t make your code very readable does it? It slows things down. </p>
<h3>Swap booleans for enumerations</h3>
<p>If we swap the bools for typedef&#8217;d enumerations then we get something more readable for the function definition:</p>
<pre>    typedef enum _processBitDepth
    {
        PROCESS_BIT_DEPTH_32,
        PROCESS_BIT_DEPTH_64,
    } PROCESS_BIT_DEPTH;

    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_NO,
        DO_SINGLE_STEP_YES,
    } DO_SINGLE_STEP;

    int attachExceptionTracerToRunningProcess(const DWORD             processId,
                                              const PROCESS_BIT_DEPTH processBitDepth,
                                              const DO_SINGLE_STEP    singleStep,
                                              const TCHAR*            dir);
</pre>
<p>Now the function call becomes:</p>
<pre>    ok = attachExceptionTracerToRunningProcess(targetProcessId, PROCESS_BIT_DEPTH_64, DO_SINGLE_STEP_NO, _T("d:\\Exception Tracer"));
</pre>
<p>and the purpose of the function arguments is explicit rather than implied.</p>
<h3>Different styles</h3>
<p>You don&#8217;t need to just use YES and NO, you can use what ever nomenclature feels correct for the situation:</p>
<pre>    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_NO,
        DO_SINGLE_STEP_YES,
    } DO_SINGLE_STEP;

    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_OFF,
        DO_SINGLE_STEP_ON,
    } DO_SINGLE_STEP;

    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_DISABLE,
        DO_SINGLE_STEP_ENABLE,
    } DO_SINGLE_STEP;

    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_STOP,
        DO_SINGLE_STEP_GO,
    } DO_SINGLE_STEP;
</pre>
<p>If you really feel TRUE/FALSE are appropriate you can do that as well. Which seems a bit odd, until you see Problem 2 and Problem 3.</p>
<pre>    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_FALSE,
        DO_SINGLE_STEP_TRUE,
    } DO_SINGLE_STEP;
</pre>
<h2>Problem 2: Implicit casting</h2>
<p>If you are using bools, many types (char, int, enumerations, etc) can implicitly convert to them without you needing to use a cast statement. This can be convenient, but it&#8217;s also an avenue for bugs.</p>
<p>If you&#8217;re using typedef&#8217;d enumerations, these implicit type conversions fail to compile.</p>
<p>You really want to be explicit about any type conversions.</p>
<h2>Problem 3: Unwanted parameter reordering</h2>
<p>If you are passing parameters through multiple functions before they finally reach the intended function it&#8217;s possible that a future edit (such as refactoring a function&#8217;s parameters) may reorder some parameters and a mistake is made during the updating of calls to the refactored function which results in parameters passed to the new function definition have been unintentionally reordered.</p>
<p>This happened to us with some boolean parameters in our code instrumentation library. We discovered the mistake when we switched to using enumerations because now each of these parameters has it&#8217;s own type.</p>
<h3>Incorrect, but compiles</h3>
<p>With the old function definition, this example will compile, but the parameters have been incorrectly switched, leading to incorrect behaviour.</p>
<pre>    int attachExceptionTracerToRunningProcess(const DWORD  processId,
                                              const bool   processBitDepth,
                                              const bool   singleStep,
                                              const TCHAR* dir);

    int doStartup(const DWORD  processId,
                  const bool   processBitDepth,
                  const bool   singleStep,
                  const TCHAR* dir)
    {
        int ok;

        ok = attachExceptionTracerToRunningProcess(processId, singleStep, processBitDepth, _T("d:\\Exception Tracer"));
    }
</pre>
<h3>Incorrect, but fails to compile</h3>
<p>With the new function definition, this example will fail to compile.</p>
<pre>    int attachExceptionTracerToRunningProcess(const DWORD             processId,
                                              const PROCESS_BIT_DEPTH processBitDepth,
                                              const DO_SINGLE_STEP    singleStep,
                                              const TCHAR*            dir);

    int doStartup(const DWORD             processId,
                  const PROCESS_BIT_DEPTH processBitDepth,
                  const DO_SINGLE_STEP    singleStep,
                  const TCHAR*            dir)
    {
        int ok;

        ok = attachExceptionTracerToRunningProcess(processId, singleStep, processBitDepth, _T("d:\\Exception Tracer"));
    }
</pre>
<h2>Making the change</h2>
<p>It&#8217;s a bit more work to create the enumeration and use it.</p>
<p>With an existing code base it can be time consuming work depending on the number of occurrences of the new enumerated type in your code base.</p>
<h3>One type at a time</h3>
<p>If you are going to make this change I would recommend changing one parameter type at a time and doing a build after each type change.</p>
<p>This seems more time consuming, but in practice we&#8217;ve found it&#8217;s easier than making multiple new types and then trying to build and dealing with the chaos that results until you&#8217;ve fixed up all the function definitions etc.</p>
<p>If, like us, you&#8217;ve got many solutions and many projects in each solution then the quickest way to do these builds is to load the solutions/projects into <a href="https://www.softwareverify.com/product/visual-studio-project-builder/">Visual Studio Project Builder</a> then build all projects of a specific configuration. This saves a lot of time.</p>
<h3>Should we change our whole codebase?</h3>
<p>There are certainly benefits to doing this. You might find some errors where parameters have been passed in the wrong order.</p>
<p>But for large codebases, changing every boolean use is probably impractical (it will take a long time). The best approach is to change them when you&#8217;re editing some code that is using them.</p>
<h2>Conclusion</h2>
<p>As you can see there are multiple benefits to using enumerations rather than booleans in your code.</p>
<p>You get improved readability and improved type safety.</p>
<p>The post <a href="https://www.softwareverify.com/blog/stop-using-booleans-theyre-hurting-your-code/">Stop using booleans, they&#8217;re hurting your code</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Secure Admin Service</title>
		<link>https://www.softwareverify.com/blog/secure-admin-service/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Thu, 19 Feb 2026 16:07:53 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12851</guid>

					<description><![CDATA[<p>This article explains the recent changes to the SVL Admin Service and to the SVL Build Service to make our tools and our services much [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/secure-admin-service/">Secure Admin Service</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This article explains the recent changes to the SVL Admin Service and to the SVL Build Service to make our tools and our services much more secure.</p>
<h2>History</h2>
<h3>April 2002 to May 2014</h3>
<p>All actions required by a Software Verify Tool were performed directly by that tool. </p>
<h3>May 2014</h3>
<p>SVL Admin Service provides functionality for various Software Verify tools that these tools cannot do running as a standard user application. </p>
<p>We wrote about this work as <a href="https://www.softwareverify.com/blog/an-end-to-unwanted-uac-prompts/">&#8220;An end to unwanted UAC prompts&#8221;</a>.</p>
<h3>February 2024</h3>
<p>During February 2024 ago we changed all the access controls on files and pipes that our tools and services use to restrict access to just the users that need to use them.</p>
<h2>The problem we wanted to solve</h2>
<p>We wanted to prevent the SVL Admin Service and the SVL Build Service from being used by bad actors as a means to attack a computer.</p>
<p>To do this we have:</p>
<ul>
<li>Encrypted the communication between any Software Verify tool and the SVL Admin Service.</li>
<li>Encrypted the communication between Visual Studio Project Builder and the SVL Build Service.</li>
<li>We&#8217;ve also replaced any commands that had the potential for abuse with commands dedicated to specific tasks that can&#8217;t be changed to something malicious.</li>
<li>We&#8217;ve also added command verification steps to ensure the appropriate digital signatures are present before we execute them or copy them.</li>
</ul>
<h2>Why we&#8217;ve made this change</h2>
<p>When we implemented the communication scheme between our tools and the SVL Admin Service we didn&#8217;t really think about the security implications as to use these pipes you&#8217;d need to know what data we send down them and have access to them as a user.</p>
<p>However, recent attacks on various computer systems, plus studying what malware authors are doing led us to conclude that we should encrypt our comms to make it very hard to monitor the comms between our tools and the service, and also make it very hard to send malicious commands to the service. The services now verify the calling application and all parameters and reject any command where the input parameters cannot be safely verified.</p>
<h2>Are my computers at risk?</h2>
<p>Software Verify&#8217;s footprint worldwide is quite small. Our tools are used worldwide, but we&#8217;re only used on developer machines and the occasional customer machine. Our tools aren&#8217;t like Notepad++ which is distributed massively around the world. Notepad++ is a great tool and that widespread distribution made it a prime candidate for an attack. This was one of the events which prompted us to improve the security of the SVL Admin Service and SVL Build Service.</p>
<p>Because our tools are not massively distributed, and are more than likely distributed on target machines that are not that valuable to a bad actor (not a C-suite machine), the ROI of attacking our tools now that we&#8217;ve made it much harder probably means it&#8217;s not worth attacking a machine hoping that our tools are installed on that machine. There are easier, more widely available targets for bad actors to go for.</p>
<p>That said, we strongly recommend updating to the most recent version of the tools released after 18/02/2026.</p>
<p><em>Please note: The <a href="https://www.softwareverify.com/products/#pythontools">Python tools</a> are legacy tools and cannot be updated. We&#8217;ll be releasing some Python capable tools to replace these later this year.</em></p>
<h2>When will this change happen?</h2>
<p>The SVL Admin Service will be upgraded when you install any of our tools downloaded from our website after 18/Feb/2026.</p>
<h2>Consequences</h2>
<p>The consequences of securing the comms between our tools and the SVL Admin Service are that once you&#8217;ve upgraded the service any already existing Software Verify tool that needs to use the SVL Admin service will be unable to communicate with the service because it will still be communicating with no encryption.</p>
<p>To fix this you will need to update each tool that uses the SVL Admin Service.</p>
<p>You can do this by:</p>
<ul>
<li>Running the tool and doing <strong>Check for Updates&#8230;</strong> from the <strong>Software Updates</strong> menu</li>
<li>For free tools: Go to the appropriate <a href="https://www.softwareverify.com/products/">software tool page</a> and download the tool again, then install it</li>
<li>For commercial tools: Login to the authorised downloads area and download the tool and install. Check your email for details</li>
</ul>
<h2>What happens if I continue trying to use a tool without updating it?</h2>
<p>The tool you are using may work for many of it&#8217;s actions, but any action that requires communicating with the SVL Admin Service will fail.</p>
<p>Any tool that tries to communicate with the encrypted SVL Admin Service without being updated will be shown this message.</p>
<p><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-12858" src="https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceWarning.png" alt="Message about failing to communicate with the SVL Admin Service" width="316" height="258" srcset="https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceWarning.png 316w, https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceWarning-300x245.png 300w" sizes="(max-width: 316px) 100vw, 316px" /></p>
<p>If you see this dialog, choose <strong>No</strong>, then update the tool you are trying to use by downloading a new version from the website.</p>
<h2>How do I know which tools to update?</h2>
<p>All our tool installers ship with a small utility which will check your machine for previous installs of our tools. These will be checked to determine if they can communicate securely with the SVL Admin Service. If they cannot communicate securely the utility will display a dialog box listing the names of the tool you need to update.</p>
<p><img decoding="async" class="alignnone size-full wp-image-12856" src="https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceChecker.png" alt="Install Secure Service Checker" width="850" height="523" srcset="https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceChecker.png 850w, https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceChecker-300x185.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceChecker-768x473.png 768w" sizes="(max-width: 850px) 100vw, 850px" /></p>
<h2>What should I do next?</h2>
<p>Find all Software Verify tools installed on your computers and update all of them to the most recent version.</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.softwareverify.com/blog/secure-admin-service/">Secure Admin Service</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Setting up ISAPI (and ASP.Net) on IIS 10</title>
		<link>https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/</link>
					<comments>https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Thu, 15 May 2025 10:50:01 +0000</pubDate>
				<category><![CDATA[Hints and tips]]></category>
		<category><![CDATA[iis 10]]></category>
		<category><![CDATA[isapi]]></category>
		<category><![CDATA[windows 10]]></category>
		<guid isPermaLink="false">https://blog.softwareverify.com/?p=2457</guid>

					<description><![CDATA[<p>Introduction OK so it&#8217;s 2020 and how many people are developing ISAPI extensions? More than you might imagine. Yeah, Ruby on Rails and Rust are [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/">Setting up ISAPI (and ASP.Net) on IIS 10</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Introduction</h2>
<p>OK so it&#8217;s 2020 and how many people are developing ISAPI extensions? More than you might imagine. Yeah, Ruby on Rails and Rust are all the rage these days, but some people still need to work with ISAPI for a bunch of business reasons.</p>
<p>I recently had to setup IIS 10 with ISAPI on Windows 10. I read a lot of articles on how to do it. None of them were complete, resulting in reading several articles to get something working, so I put this together, mainly for my own benefit (because I really don&#8217;t need to spend that much time doing this again!). I&#8217;m sharing it so you don&#8217;t have to go through this. </p>
<p>I was trying to get a simple ISAPI extension to work before trying anything else. My guess is most of you are working on legacy code, but a few of you may have been instructed to write a new ISAPI. Here&#8217;s a good starting point for a simple ISAPI extension if you haven&#8217;t already written one.</p>
<p>Creating an ISAPI extension: <a href="https://www.codeproject.com/Articles/1432/What-is-an-ISAPI-Extension">https://www.codeproject.com/Articles/1432/What-is-an-ISAPI-Extension</a></p>
<h3>ASP.Net</h3>
<p>I&#8217;m also going to very briefly mention installing ASP.Net as well.</p>
<h3>32 bit ISAPI</h3>
<p>There&#8217;s an interesting gotcha if you&#8217;re developing a 32 bit ISAPI extension. Don&#8217;t worry I cover that at the end.</p>
<h3>Windows 10 and Windows 11</h3>
<p>The instructions in this article work for both Windows 10 and Windows 11. The process is identical on both operating systems.</p>
<h2>Installing IIS components</h2>
<p>IIS components are installed via the Windows features dialog.</p>
<p>In the Windows 10 search box type <em>&#8220;Turn Windows features on and off&#8221;</em>, when windows shows you the result that matches press return (or click it).</p>
<p><img decoding="async" class="alignleft size-full wp-image-2459" src="https://www.softwareverify.com/wp-content/uploads/2020/04/TurnWindowsFeaturesOnAndOff.png" alt="Turn Windows features on and off" width="1152" height="680" /><br />
<br clear="all" />
</p>
<p>The feature selection box is displayed. Select the items highlighted red in the image shown below. Click OK.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11384" src="https://www.softwareverify.com/wp-content/uploads/2020/04/turn-windows-features-on-or-off.png" alt="Turn Windows features on or off ISAPI and ASP.NET" width="415" height="570" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/turn-windows-features-on-or-off.png 415w, https://www.softwareverify.com/wp-content/uploads/2020/04/turn-windows-features-on-or-off-218x300.png 218w" sizes="auto, (max-width: 415px) 100vw, 415px" /><br />
<br clear="all" />
</p>
<p>If you&#8217;ve already got partway through configuring IIS Manager and have realised you don&#8217;t have all the required components installed that&#8217;s OK, just install them and then close IIS Manager and reopen it (I found that if I didn&#8217;t do that not all the component parts would show in IIS Manager, making finding (for example) ISAPI and CGI Restrictions impossible.</p>
<h3>ASP.Net</h3>
<p>If you&#8217;re working with ASP.Net, enable the items above that are identified as ASP.NET and the .Net Extensibility options as well.</p>
<h2>Configuring IIS Manager</h2>
<p>Start Internet Information Services Manager.</p>
<p>In the Windows 10 search box type <em>&#8220;Internet Information Services Manager&#8221;</em>, when windows shows you the result that matches press return (or click it).</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11247" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Start-Menu.png" alt="Start menu Internet Information Services Manager" width="834" height="683" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Start-Menu.png 834w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Start-Menu-300x246.png 300w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Start-Menu-768x629.png 768w" sizes="auto, (max-width: 834px) 100vw, 834px" /></p>
<h3>Website</h3>
<p>First of all we need a website to work with. If you&#8217;ve already got one skip the next few lines.</p>
<ol>
<li>Add a test website. Right click on <em>&#8220;Sites&#8221;</em> in the left hand menu and choose <em>&#8220;Add Website&#8230;&#8221;
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11248" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite.png" alt="IIS context menu Add Website" width="319" height="184" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite.png 319w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite-300x173.png 300w" sizes="auto, (max-width: 319px) 100vw, 319px" /><br />
</em></li>
<li>The Add Website dialog is displayed.
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11249" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite-Dialog.png" alt="IIS Add Website dialog" width="585" height="672" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite-Dialog.png 585w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite-Dialog-261x300.png 261w" sizes="auto, (max-width: 585px) 100vw, 585px" /></li>
<li>Choose a website name. For example: <strong>&#8220;test&#8221;</strong>.</li>
<li>Choose a location for the website. For example: <strong>C:\testISAPIWebsite</strong></li>
<li>Change the port number (just for testing) so that it doesn&#8217;t conflict with any other sites you have. For example: <strong>81</strong>.</li>
<li><a href="https://www.softwareverify.com/blog/setting-directory-permissions-for-user-group-iis-iusrs/">Modify the security permissions for the directory</a> you specified in step 4 to allow write and/or execute permissions if you need these permissions. </li>
</ol>
<h3 id="handlerMappings">Handler Mappings</h3>
<ol>
<li>Select the server node on the left hand side and double click click on Handler Mappings on the right hand size.
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2460" src="https://www.softwareverify.com/wp-content/uploads/2020/04/HandlerMappings.png" alt="IIS handler mappings" width="1137" height="457" /></p>
</li>
<li>The handler mappings are displayed.
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2461" src="https://www.softwareverify.com/wp-content/uploads/2020/04/HandlerMappingsValues.png" alt="IIS handler mappings values" width="816" height="319" /><br />
<br clear="all" />
</p>
</li>
<li>Right click in empty space and choose <em>&#8220;Edit Feature Permissions&#8230;&#8221;</em>.
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11254" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Edit-Feature-Permissions.png" alt="IIS Edit Feature Permissions" width="215" height="191" /></li>
<li>The Edit Feature Permissions dialog is displayed. Enable <strong>Read</strong>, <strong>Script</strong> and <strong>Execute</strong> permissions. When you select the execute check box you&#8217;ll notice the entry for ISAPI dlls is added to the displayed Handler Mappings. Click OK.
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2462" src="https://www.softwareverify.com/wp-content/uploads/2020/04/EditFeaturePermissions.png" alt="Edit feature permissions" width="770" height="471" /><br />
<br clear="all" />
</p>
</li>
</ol>
<h3 id="SoftwareRestrictions">ISAPI and CGI Restrictions</h3>
<ol>
<li>Select the server node on the left hand side and double click click on <em>&#8220;ISAPI and CGI Restrictions&#8221;</em> on the right hand size.
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11250" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions.png" alt="IIS CGI-ISAPI restrictions" width="1424" height="750" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions.png 1424w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions-300x158.png 300w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions-1024x539.png 1024w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions-768x404.png 768w" sizes="auto, (max-width: 1424px) 100vw, 1424px" /></li>
<li>Right click in empty space and choose <em>&#8220;Add&#8230;&#8221;</em>.
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11251" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Add.png" alt="IIS GCI-ISAPI restrictions Add" width="191" height="81" /></li>
<li>Add the path to your ISAPI dll, a description and select the check box so that it is allowed to execute. Click OK.
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2464" src="https://www.softwareverify.com/wp-content/uploads/2020/04/ISAPIandCGIRestrictionsAdd.png" alt="ISAPI and CGI restrictions" width="583" height="431" /><br />
<br clear="all" />
</p>
</li>
<li>
<p>This will place a web.config in the directory that contains the DLL. It will look something like this:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;configuration&gt;
    &lt;system.webServer&gt;
        &lt;handlers accessPolicy="Read, Execute, Script"&gt;
            &lt;remove name="ISAPI-dll" /&gt;
            &lt;add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" scriptProcessor="C:\testISAPIWebsite\validate.dll" resourceType="File" requireAccess="Execute" allowPathInfo="true" preCondition="bitness32" /&gt;
        &lt;/handlers&gt;
    &lt;/system.webServer&gt;
&lt;/configuration&gt;
</pre>
</li>
</ol>
<h3 id="32bit">32 bit ISAPI extensions</h3>
<p>If your ISAPI is 32 bit you&#8217;ll need to enable them. Go to application pools (under the server node), select the application pool that your website is in, right click, choose <em>&#8220;Advanced Settings&#8230;&#8221;</em>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11645" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ApplicationPools-AdvancedSettings.png" alt="IIS Application Pools Advanced Settings" width="832" height="660" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ApplicationPools-AdvancedSettings.png 832w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ApplicationPools-AdvancedSettings-300x238.png 300w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ApplicationPools-AdvancedSettings-768x609.png 768w" sizes="auto, (max-width: 832px) 100vw, 832px" /></p>
<p>Change the <em>&#8220;Enable 32-Bit Applications&#8221;</em> setting to <strong>True</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11648" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-32bit-Extensions.png" alt="IIS ISAPI 32 bit extensions" width="432" height="541" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-32bit-Extensions.png 432w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-32bit-Extensions-240x300.png 240w" sizes="auto, (max-width: 432px) 100vw, 432px" /></p>
<h3 id="64bit">64 bit ISAPI extensions</h3>
<p>If your ISAPI is 64 bit you&#8217;ll need to ensure that you haven&#8217;t got 32 bit extensions enabled. Go to application pools (under the server node), select the application pool that your website is in, right click, choose <em>&#8220;Advanced Settings&#8230;&#8221;</em>. Change the <em>&#8220;Enable 32-Bit Applications&#8221;</em> setting to <strong>False</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11649" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-64bit-Extensions.png" alt="IIS ISAPI 64 bit extensions" width="434" height="541" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-64bit-Extensions.png 434w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-64bit-Extensions-241x300.png 241w" sizes="auto, (max-width: 434px) 100vw, 434px" /></p>
<h2>Trying out the website</h2>
<p>If we assume your ISAPI is called <strong>validate.dll</strong> you should be able to test your ISAPI in a browser using <strong>http://localhost:81/validate.dll?12345678</strong></p>
<h3>Authentication problems</h3>
<p>If when trying to view your web pages you get strange error messages, select the server node on the left then go to <em>&#8220;Feature Delegation&#8221;</em> and turn any entries that are <em>&#8220;Read only&#8221;</em> to <em>&#8220;Read/Write&#8221;</em>. Then restart the server (top of the right hand bar).</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11252" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation.png" alt="IIS Feature Delegation" width="1424" height="750" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation.png 1424w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation-300x158.png 300w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation-1024x539.png 1024w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation-768x404.png 768w" sizes="auto, (max-width: 1424px) 100vw, 1424px" /></p>
<p>Note that I&#8217;m assuming you&#8217;re working on a Dev machine. If you&#8217;re working on a production machine you might want to be a bit less cavalier than just turning all settings to Read/Write &#8211; work through them one at a time to find out what you need and change only that.</p>
<h3>Directory Permissions</h3>
<p>If you&#8217;re having problems with directory permissions that aren&#8217;t managed by IIS Manager you should read this article about changing <a href="https://www.softwareverify.com/blog/setting-directory-permissions-for-user-group-iis-iusrs/">directory permissions for IIS_IUSRS</a>.</p>
<h3>Server Errors</h3>
<p>If you&#8217;re getting error pages from the server describing various server errors you should take a look at <a href="https://www.softwareverify.com/blog/common-iis-server-errors/">Common IIS Server Errors</a>.</p>
<p>The post <a href="https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/">Setting up ISAPI (and ASP.Net) on IIS 10</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Failing email</title>
		<link>https://www.softwareverify.com/blog/failing-email/</link>
					<comments>https://www.softwareverify.com/blog/failing-email/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Tue, 18 Feb 2025 18:39:32 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12684</guid>

					<description><![CDATA[<p>Last week, from Thursday 13th February to the evening of Sunday 16th February our email servers were temporarily unreachable. This was caused by a failure [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/failing-email/">Failing email</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Last week, from Thursday 13th February to the evening of Sunday 16th February our email servers were temporarily unreachable.</p>
<p>This was caused by a failure with an upstream DNS provider.</p>
<p>After waiting for them to fix the problem for far too long we changed DNS providers. </p>
<p>We started receiving email again during late Sunday evening / early Monday.</p>
<p>If you tried to contact us and got a bounce message, this is the reason why.</p>
<p>Sorry for any inconvenience.</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.softwareverify.com/blog/failing-email/">Failing email</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/failing-email/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to read embedded data from a resource</title>
		<link>https://www.softwareverify.com/blog/how-to-read-embedded-data-from-a-resource/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Wed, 22 Jan 2025 11:58:05 +0000</pubDate>
				<category><![CDATA[Hints and tips]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[resource]]></category>
		<guid isPermaLink="false">http://www.softwareverify.com/software-verify-blog/?p=590</guid>

					<description><![CDATA[<p>In the previous article, I showed you how to embed data into a custom resource in your application. In this article, I&#8217;m going to show [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/how-to-read-embedded-data-from-a-resource/">How to read embedded data from a resource</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In the previous article, I showed you how to <a href="https://www.softwareverify.com/software-verify-blog/?p=589" target="_blank" rel="noopener noreferrer">embed data into a custom resource</a> in your application.</p>


<p>In this article, I&#8217;m going to show you how to extract the same data using the Win32 API for use in your application at runtime.</p>


<p>To extract data from a resource in an executable we need some information:</p>


<ul class="wp-block-list">
	<li>
<p>Executable name.</p>
</li>
	<li>
<p>Custom resource name.</p>
</li>
	<li>
<p>Custom resource type name.</p>
</li>
</ul>


<p>In our previous example, the executable name was <strong>mvJavaDetective.dll</strong>, the custom resource type name was <span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;CLASSFILE&#8221;</span> and the custom resource name was <span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;myJavaSpy&#8221;</span>.</p>


<h2 class="wp-block-heading">The API</h2>


<h3 class="wp-block-heading">FindResource</h3>


<pre class="wp-block-code"><code>    HRSRC FindResource(HMODULE hModule,
                       LPCTSTR lpName,
                       LPCTSTR lpType);
</code></pre>


<p>Call <strong>FindResource()</strong> to find a resource in an executable and return a resource handle.</p>


<p>The executable is specified using a module handle that represents a module loaded in the current program. If the module is currently loaded you can get a handle to it using <strong>GetModuleHandle()</strong>. If the module is not currently loaded you can load it with <strong>LoadLibrary()</strong>.</p>


<p>The resource is identified by its custom resource name and custom resource type.</p>


<h3 class="wp-block-heading">LoadResource</h3>


<pre class="wp-block-code"><code>    HGLOBAL LoadResource(HMODULE hModule,
                         HRSRC   hResInfo);
</code></pre>


<p>Call <strong>LoadResource()</strong> to load the resource passings the module handle and the resource handle from <strong>FindResource()</strong> as parameters.</p>


<p>The returned handle should not be passed to any Global memory function for deallocation.</p>


<h3 class="wp-block-heading">LockResource</h3>


<pre class="wp-block-code"><code>    LPVOID LockResource(HGLOBAL hResData);
</code></pre>


<p>Call <strong>LockResource()</strong> to lock the resource in memory. Pass the handle returned by <strong>LoadResource()</strong> as the input parameter.</p>


<p>If the call succeeds a pointer to the data represented by the handle is returned.</p>


<h3 class="wp-block-heading">SizeofResource</h3>


<pre class="wp-block-code"><code>    DWORD SizeofResource(HMODULE hModule,
                         HRSRC   hResInfo);
</code></pre>


<p>Call <strong>SizeofResource()</strong> to determine the size of a resource. Pass the module handle and the handle returned from <strong>FindResource()</strong> as input parameters.</p>


<p>The return value specifies the size of the resource.</p>


<h2 class="wp-block-heading">Putting it together</h2>


<p>In the previous example our example DLL myJavaDetective.dll had a class <strong>myJavaSpy.class</strong> embedded into a resource with the type <span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;CLASSFILE&#8221;</span> and name <span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;myJavaSpy&#8221;</span>. I will now show you how to extract the <strong>myJavaSpy.class</strong> byte codes from the resource.</p>


<p>First we need to get the module handle of the executable (<strong>myJavaDetective.dll</strong>) containing the <strong>myJavaSpy.class</strong>. For this example we will assume that <strong>myJavaDetective.dll</strong> is already loaded into memory.</p>


<p>Call <strong>GetModuleHandle()</strong> with the name of the DLL holding the resource (<span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;myJavaDetective.dll&#8221;</span>). The return value is the module handle.</p>


<pre class="wp-block-code"><code>	HMODULE	hModJavaDetective;

	hModJavaDetective = GetModuleHandle("myJavaDetective.dll");
</code></pre>


<p>Once we have the module handle we can attempt to find the resource in the executable. We don&#8217;t need to check for a NULL module handle as <strong>FindResource()</strong> handles that and will return a NULL resource handle (just as it will if the resource is not embedded in the executable).</p>


<pre class="wp-block-code"><code>	jbyte	*classBytes = NULL;
	DWORD	classBytesLength = 0;
	HRSRC	hResource;

	hResource = FindResource(hModJavaDetective,
							 _T("myJavaSpy"),
							 _T("CLASSFILE"));
	if (hResource != NULL)
	{
</code></pre>


<p>If <strong>FindResource()</strong> returns a non NULL handle the resource has been found. Now we must load the resource using <strong>LoadResource()</strong>.</p>


<pre class="wp-block-code"><code>		HGLOBAL	hResourceMemory;

		hResourceMemory = LoadResource(hModJavaDetective, hResource);
		if (hResourceMemory != NULL)
		{
</code></pre>


<p>If <strong>LoadResource()</strong> returns a non NULL handle the resource has been correctly loaded from the executable. This returns a handle of type HGLOBAL. Caution you must not pass this handle to any HGLOBAL related functions such as <strong>GlobalFree()</strong> or <strong>GlobalRealloc()</strong> as this handle does not represent a memory allocation. This type is used for backward compatibility with earlier versions of the Windows API.</p>


<p>Before we can use the data we must convert the returned handle into a pointer to the data by calling <strong>LockResource()</strong>. We also want to know the size of the data in the resource so we call <strong>SizeofResource()</strong> to determine the size. The pointer returned by <strong>LockResource()</strong> must not be passed to any memory deallocation functions &#8211; it does not need to be deallocated or unlocked.</p>


<pre class="wp-block-code"><code>			void	*ptr;
			DWORD	size;

			ptr = LockResource(hResourceMemory);
			size = SizeofResource(hModInjectedJVMTI, hResource);
			if (ptr != NULL)
			{
</code></pre>


<p>If <strong>LockResource()</strong> returns a non NULL pointer the pointer represents the data embedded in the executable.</p>


<p>Now we have the data we make a copy for our own use and continue as normal. This step is optional, you can use the data directly from the returned pointer if you wish.</p>


<pre class="wp-block-code"><code>				classBytes = new jbyte [size];
				if (classBytes != NULL)
				{
					memcpy(classBytes, ptr, size);
					classBytesLength = size;
				}
			}
		}

		// CAUTION! LoadResource() and LockResource() DO NOT allocate handles or locks, 
		// read the documentation
	}
</code></pre>


<p>Now that we have extracted the data from the resource embedded into the executable we can use the data as normal. For this example I will conclude by using the extracted Java class bytescodes to define a Java class in a Java Virtual Machine.</p>


<pre class="wp-block-code"><code>	if (classBytes != NULL)
	{
		// define our class, must have same name as class file bytes
		// pass NULL for the class loader - use default class loader

		jclass		klass = 0;

		klass = jniEnv-&gt;DefineClass(SVL_COVERAGE_CLASS, NULL, classBytes, classBytesLength);
		if (klass != 0)
		{
                    // class defined correctly
		}

		// tidy up

		delete [] classBytes;
	}
</code></pre>


<h2 class="wp-block-heading">Wrap up</h2>


<p>Now you know how to embed data in an executable at runtime (and after the fact with the utility presented in the previous article) and how to extract data from an executable at runtime. The techniques are quite straightforward to master and allow you to easily embed data for you to use at runtime without worrying about distributing and locating extra data files with your application.</p>

<p>&nbsp;</p><p>The post <a href="https://www.softwareverify.com/blog/how-to-read-embedded-data-from-a-resource/">How to read embedded data from a resource</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Debugging a crash with single stepping</title>
		<link>https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/</link>
					<comments>https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Tue, 21 Jan 2025 15:37:43 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Flow Tracing]]></category>
		<category><![CDATA[execution tracing]]></category>
		<category><![CDATA[single step]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12635</guid>

					<description><![CDATA[<p>If you&#8217;ve ever used a debugger you&#8217;re probably familiar with the concept of single stepping through code &#8211; executing one instruction at a time until [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/">Debugging a crash with single stepping</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;ve ever used a debugger you&#8217;re probably familiar with the concept of single stepping through code &#8211; executing one instruction at a time until you find the particular instruction that causes the crash.</p>
<h2>The Problem &#8211; Inaccessible Locations</h2>
<p>But what if the crash happens in somewhere that&#8217;s hard for you to debug, for example deep inside ExitProcess() or millions of instructions after the last location that you know about that is in your code?</p>
<h2>The Solution &#8211; Automation</h2>
<p>The solution to this problem is a dedicated tool that will single step through your code automatically without requiring you to tell the debugger to single step the next instruction. </p>
<p>Exception Tracer has a dedicated single-step mode that you can use for this.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12640" src="https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStep.png" alt="Exception Tracer user interface single step" width="691" height="81" srcset="https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStep.png 691w, https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStep-300x35.png 300w" sizes="auto, (max-width: 691px) 100vw, 691px" /></p>
<p>However, using Exception Tracer from it&#8217;s user interface you can attach to your program, but that doesn&#8217;t guarantee single stepping will happen in the right place for you. You could end up single stepping through tens of thousands of lines of code (millions of instructions) that you don&#8217;t need to before you get to the part of the program that you know is interesting. You could spend hours waiting for the trace to get to the part of the code that you think is going to be interesting for the purposes of understanding the bug. I know, I&#8217;ve waited overnight for single stepping results.</p>
<p>What if you could be more specific about when you choose to attach Exception Tracer you could save hours of time, increasing your productivity?</p>
<p>The solution is to add a single call to your application to launch exception tracer from within your program so that Exception Tracer starts single stepping your application from that exact location.</p>
<pre>attachExceptionTracerX64(GetCurrentProcessId());</pre>
<p>The function looks like this:</p>
<pre> 
static const TCHAR *ET_X86_PATH = _T("C:\\Program Files (x86)\\Software Verify\\ExceptionTracer\\exceptionTracer.exe");
static const TCHAR *ET_X64_PATH = _T("C:\\Program Files (x86)\\Software Verify\\ExceptionTracer\\exceptionTracer_x64.exe");

void attachExceptionTracer_internal(const TCHAR*    pathToExceptionTracer,
                                    DWORD           processId)
{
    int                    b;
    DWORD                  dwCreateFlags;
    STARTUPINFO            startupInfo;    // put info about startup here for CreateProcess()
    PROCESS_INFORMATION    procInfo;        // info about the process is placed here
    CString                theCmdLine;

    theCmdLine.Format(_T("%s /process %d /singleStepRequired:On"), pathToExceptionTracer, processId);

    startupInfo.cb = sizeof(STARTUPINFO);
    startupInfo.lpReserved = NULL;
    startupInfo.lpDesktop = NULL;
    startupInfo.lpTitle = NULL;
    startupInfo.dwX = 0;
    startupInfo.dwY = 0;
    startupInfo.dwXSize = 400;
    startupInfo.dwYSize = 400;
    startupInfo.dwXCountChars = 40;
    startupInfo.dwYCountChars = 25;
    startupInfo.dwFillAttribute = 0;
    startupInfo.dwFlags = STARTF_USESHOWWINDOW;
    startupInfo.wShowWindow = SW_SHOW;
    startupInfo.cbReserved2 = 0;
    startupInfo.lpReserved2 = NULL;
    startupInfo.hStdInput = NULL;
    startupInfo.hStdOutput = NULL;
    startupInfo.hStdError = NULL;

    procInfo.hProcess = NULL;
    procInfo.hThread = NULL;
    procInfo.dwProcessId = NULL;
    procInfo.dwThreadId = NULL;

    dwCreateFlags = NORMAL_PRIORITY_CLASS;

    b = CreateProcess(NULL,                                  // program
                      (TCHAR *)(const TCHAR *)theCmdLine,    // command line
                      NULL,                                  // process attributes (use default)
                      NULL,                                  // thread attributes (use default)
                      FALSE,                                 // inheritance (don't)
                      dwCreateFlags,                         // how to create the process
                      NULL,                                  // environment (use parent's, ie this)
                      NULL,                                  // current directory (same as this process if NULL)
                      &amp;startupInfo,                          // startup info
                      &amp;procInfo);                            // process info (return value)
    if (b)
    {
        WaitForInputIdle(procInfo.hProcess, INFINITE);

        CloseHandle(procInfo.hProcess);
        CloseHandle(procInfo.hThread);
    }
}

void attachExceptionTracerX86(DWORD	processId)
{
    attachExceptionTracer_internal(ET_X86_PATH, processId);
}

void attachExceptionTracerX64(DWORD	processId)
{
    attachExceptionTracer_internal(ET_X64_PATH, processId);
}
</pre>
<p>There&#8217;s also some helper functions to calculate the path to Exception Tracer based on values stored in the registry. All you need to do is:</p>
<ol>
<li><strong>#include attachExceptionTracer.inl</strong> into the source file where you want to start Exception Tracer</li>
<li>call <strong>attachExceptionTracerX86 </strong>or <strong>attachExceptionTracerX64</strong> as appropriate to start Exception Tracer</li>
</ol>
<p>Exception Tracer will attach to the application with single stepping enabled and run until the program exits. After the program exits the trace will be processed and then displayed for you to analyse.</p>
<p>The trace shown below shows single stepping into a buffer overrun crash being detected.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12643" src="https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace.png" alt="Exception Tracer showing a trace full of single step entries that are part of a buffer overrun crash" width="1183" height="679" srcset="https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace.png 1183w, https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace-300x172.png 300w, https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace-1024x588.png 1024w, https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace-768x441.png 768w" sizes="auto, (max-width: 1183px) 100vw, 1183px" /></p>
<p>The post <a href="https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/">Debugging a crash with single stepping</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Why does the SVL Admin Service inject into processes?</title>
		<link>https://www.softwareverify.com/blog/why-does-the-svl-admin-service-inject-into-processes/</link>
					<comments>https://www.softwareverify.com/blog/why-does-the-svl-admin-service-inject-into-processes/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Wed, 12 Jun 2024 16:04:28 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Communication]]></category>
		<category><![CDATA[injection]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12567</guid>

					<description><![CDATA[<p>Why does the SVL Admin Service inject into processes? We were recently asked this question by a customer because their security team was concerned that [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/why-does-the-svl-admin-service-inject-into-processes/">Why does the SVL Admin Service inject into processes?</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<blockquote>
<p>Why does the SVL Admin Service inject into processes?</p>
</blockquote>
<p>We were recently asked this question by a customer because their security team was concerned that this behaviour was unexpected and might be malicious.</p>
<p>In this article I&#8217;m going to describe every Software Verify process that injects into another process and explain why it is doing that.</p>
<h2>Summary</h2>
<p>Before I do that, here&#8217;s the summary:</p>
<ul>
<li>We inject into other processes mainly to set environment variables that will allow .Net and .Net Core processes to load our .Net profiler. </li>
<li>We inject into other processes mainly to delete environment variables that will allow .Net and .Net Core processes to load our .Net profiler.</li>
<li>We inject into other processes sometimes to attach to a native process to allow profiling of that process. This is the <strong>Inject into running process&#8230;</strong> option on the <strong>Launch</strong> menu.</li>
<li>We can also eject a DLL from a target process.</li>
</ul>
<h2>Setting Environment Variables</h2>
<p>We set environment variables in a target process &#8211; used to set .Net Profiler environment variables.</p>
<ul>
<li>We allocate some memory in the target process and setup the environment variables values we want to set.</li>
<li>We then create a remote thread in the target process and call the <strong>SetEnvironmentVariable()</strong> function (found in <strong>kernel32.dll</strong> in the target process) with a pointer to the memory setup previously.</li>
</ul>
<h2>Deleting Environment Variables</h2>
<p>We delete environment variables in a target process &#8211; used to reset .Net Profiler environment variables.</p>
<ul>
<li>We allocate some memory in the target process and setup the environment variables values we want to delete.</li>
<li>We then create a remote thread in the target process and call the <strong>SetEnvironmentVariable()</strong> function (found in <strong>kernel32.dll</strong> in the target process) with a pointer to the memory setup previously.</li>
</ul>
<h2>Injecting a DLL into a target process</h2>
<p>We inject Software Verify DLLs into a target process &#8211; used to attach to processes that are already running.</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li>We create a remote thread in the target process.</li>
<li>The thread loads the Software Verify DLL we want loaded.</li>
<li>The thread calls the function we want called in that DLL. There are two use cases for this.</li>
</ul>
</li>
</ul>
<h3>Injecting a profiler into an application that is about to start</h3>
<p>This is the <strong>Launch Application&#8230;</strong> option on the <strong>Launch</strong> menu.</p>
<p>We start the target application in a suspended state, then modify the entry point code to run our code that will load the native profiler before any other code gets executed. This allows us to monitor more of your application&#8217;s behaviour than any other method. It is also more reliable and doesn&#8217;t suffer from the risk of deadlocks that Injecting a profiler into a running application has.</p>
<p><em>Note that for this method we do not create a remote thread, it is not required.</em></p>
<p>The function called is &#8220;startProfiler&#8221; or &#8220;startProfilerEx&#8221;.</p>
<p>The DLL that will be injected depends on the software tool being used.</p>
<table style="border-collapse: collapse; width: 33.9813%;">
<tbody>
<tr>
<td style="width: 21.5737%;">Bug Validator</td>
<td style="width: 10.5102%;">svlBugValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Coverage Validator x86</td>
<td style="width: 10.5102%;">svlCoverageValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Coverage Validator x64</td>
<td style="width: 10.5102%;">svlCoverageValidatorStub_x64.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Memory Validator x86</td>
<td style="width: 10.5102%;">svlMemoryValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Memory Validator x64</td>
<td style="width: 10.5102%;">svlMemoryValidatorStub_x64.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Performance Validator x86</td>
<td style="width: 10.5102%;">svlPerformanceValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Performance Validator x64</td>
<td style="width: 10.5102%;">svlPerformanceValidatorStub_x64.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Thread Validator x86</td>
<td style="width: 10.5102%;">svlThreadValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Thread Validator x64</td>
<td style="width: 10.5102%;">svlThreadValidatorStub_x64.dll</td>
</tr>
</tbody>
</table>
<h3>Injecting a profiler into a running application</h3>
<p>This is the <strong>Inject into running process&#8230;</strong> option on the <strong>Launch</strong> menu.</p>
<p>There is a risk of deadlock with this method because it is impossible to know the state of locks and critical sections that are already active before you inject to a running application (not the same as attaching a debugger to a running application &#8211; the debugger is a separate process). <strong><em>We do note in the software documentation that you should always prefer Launch Application to Inject into running process.</em></strong></p>
<p>The function called is &#8220;startProfiler&#8221; or &#8220;startProfilerEx&#8221;.</p>
<p>The DLL that will be injected depends on the software tool being used.</p>
<table style="border-collapse: collapse; width: 33.9813%;">
<tbody>
<tr>
<td style="width: 21.5737%;">Bug Validator</td>
<td style="width: 10.5102%;">svlBugValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Coverage Validator x86</td>
<td style="width: 10.5102%;">svlCoverageValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Coverage Validator x64</td>
<td style="width: 10.5102%;">svlCoverageValidatorStub_x64.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Memory Validator x86</td>
<td style="width: 10.5102%;">svlMemoryValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Memory Validator x64</td>
<td style="width: 10.5102%;">svlMemoryValidatorStub_x64.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Performance Validator x86</td>
<td style="width: 10.5102%;">svlPerformanceValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Performance Validator x64</td>
<td style="width: 10.5102%;">svlPerformanceValidatorStub_x64.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Thread Validator x86</td>
<td style="width: 10.5102%;">svlThreadValidatorStub.dll</td>
</tr>
<tr>
<td style="width: 21.5737%;">Thread Validator x64</td>
<td style="width: 10.5102%;">svlThreadValidatorStub_x64.dll</td>
</tr>
</tbody>
</table>
<h3>Injecting a DLL that sets some environment variables</h3>
<p>Injecting a DLL that sets some environment variables via the <strong>DllMain()</strong> function.</p>
<p>There is no risk of deadlock injecting these DLLs, they do so little work you can&#8217;t trigger that sort of problem.</p>
<p>The DLL unloads immediately because once the environment variables are set it has no more work to do. </p>
<table style="border-collapse: collapse; width: 34.0478%;">
<tbody>
<tr>
<td style="width: 13.4546%;">Bug Validator</td>
<td style="width: 20.5935%;">svlBvSetEnv.dll</td>
</tr>
<tr>
<td style="width: 13.4546%;">Coverage Validator x86</td>
<td style="width: 20.5935%;">svlCvSetEnv.dll</td>
</tr>
<tr>
<td style="width: 13.4546%;">Coverage Validator x64</td>
<td style="width: 20.5935%;">svlCvSetEnv_x64.dll</td>
</tr>
<tr>
<td style="width: 13.4546%;">Memory Validator x86</td>
<td style="width: 20.5935%;">svlMvSetEnv.dll</td>
</tr>
<tr>
<td style="width: 13.4546%;">Memory Validator x64</td>
<td style="width: 20.5935%;">svlMvSetEnv_x64.dll</td>
</tr>
<tr>
<td style="width: 13.4546%;">Performance Validator x86</td>
<td style="width: 20.5935%;">svlPvSetEnv.dll</td>
</tr>
<tr>
<td style="width: 13.4546%;">Performance Validator x64</td>
<td style="width: 20.5935%;">svlPvSetEnv_x64.dll</td>
</tr>
<tr>
<td style="width: 13.4546%;">Thread Validator x86</td>
<td style="width: 20.5935%;">svlTvSetEnv.dll</td>
</tr>
<tr>
<td style="width: 13.4546%;">Thread Validator x64</td>
<td style="width: 20.5935%;">svlTvSetEnv_x64.dll</td>
</tr>
</tbody>
</table>
<p>The above are used when working with ASP.Net. The processes injected into are:</p>
<table style="border-collapse: collapse; width: 34.0467%;">
<tbody>
<tr>
<td style="width: 10.2989%;">mmc.exe</td>
<td style="width: 45.3996%;">Applications</td>
</tr>
<tr>
<td style="width: 10.2989%;">cmd.exe</td>
<td style="width: 45.3996%;">Applications</td>
</tr>
<tr>
<td style="width: 10.2989%;">explorer.exe</td>
<td style="width: 45.3996%;">Applications</td>
</tr>
<tr>
<td style="width: 10.2989%;">inetinfo.exe</td>
<td style="width: 45.3996%;">Internet Information Server</td>
</tr>
<tr>
<td style="width: 10.2989%;">services.exe</td>
<td style="width: 45.3996%;">Services</td>
</tr>
<tr>
<td style="width: 10.2989%;">svchost.exe</td>
<td style="width: 45.3996%;">Services</td>
</tr>
</tbody>
</table>
<p>The reasons these processes are injected into is because these are the processes that may launch other processes, and those processes inherit their environment variables from the process launching them.</p>
<p>The applications that may initiate this are:</p>
<ul>
<li>bugValidator.exe</li>
<li>coverageValidator.exe</li>
<li>coverageValidator_x64.exe</li>
<li>memoryValidator.exe</li>
<li>memoryValidator_x64.exe</li>
<li>performanceValidator.exe</li>
<li>performanceValidator_x64.exe</li>
<li>threadValidator.exe</li>
<li>threadValidator_x64.exe</li>
</ul>
<p>The services that may initiate this are:</p>
<ul>
<li>svlAdminService.exe via svlInject.exe</li>
<li>svlAdminService.exe via svlInject_x64.exe</li>
<li>svlAdminService_x64.exe via svlInject.exe</li>
<li>svlAdminService_x64.exe via svlInject_x64.exe</li>
</ul>
<p>These may also be called indirectly via the resetDotNetProfiler.exe tool which will reset all .Net Profiler environment variables.</p>
<p><strong>Why do Bug Validator and Thread Validator set .Net profiler environment variables when these profilers only profile native code?</strong></p>
<p>The reason for this is mixed mode .Net processes that execute both .Net and native code. If BV and TV are to profile the native code in these mixed mode processes we still need to load a .Net profiler into these processes so that the native profiling code can be loaded into the target process.</p>
<p><strong>Why do x86 processes inject into x64 processes?</strong></p>
<p>The reason for this is that on 64 bit systems it is most likely that a 64 bit process will start a 32 bit process that may be the target for the software tool you are using. We need to set the .Net profiling environment variables appropriately for that task. This is why svlAdminService.exe calls svlInject_x64.exe to inject 64 bit DLLs into 64 bit target processes.</p>
<h2>Ejecting a DLL into a target process</h2>
<p>We remove Software Verify DLLs from a target process &#8211; used to remove DLLs from a process that we have previously inject into a process.</p>
<ul>
<li>We create a remote thread in the target process then call FreeLibrary() with the base address of the DLL in the target process.</li>
</ul>
<h2>Conclusion</h2>
<p>Some of Software Verify&#8217;s software tools inject DLLs into other processes.</p>
<p>This is done to manage .Net Profiler environment variables, or to profile already running native applications when instructed to do so by the user of the software.</p>
<p>There is nothing malicious about this behaviour. It is by design, and is necessary for the correct functioning of the software when working with .Net, .Net Core and debugging applications that are already running.</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.softwareverify.com/blog/why-does-the-svl-admin-service-inject-into-processes/">Why does the SVL Admin Service inject into processes?</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/why-does-the-svl-admin-service-inject-into-processes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Potential misleading digitial signature warning with automatic updates</title>
		<link>https://www.softwareverify.com/blog/potential-misleading-digitial-signature-warning-with-automatic-updates/</link>
					<comments>https://www.softwareverify.com/blog/potential-misleading-digitial-signature-warning-with-automatic-updates/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Mon, 26 Feb 2024 15:11:07 +0000</pubDate>
				<category><![CDATA[Communication]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[software updates]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12533</guid>

					<description><![CDATA[<p>If you&#8217;ve installed any of our commercial tools (not evaluation versions) before January 26 2024, then enabled automatic updates and tried to update your software [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/potential-misleading-digitial-signature-warning-with-automatic-updates/">Potential misleading digitial signature warning with automatic updates</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;ve installed any of our commercial tools (not evaluation versions) before January 26 2024, then enabled automatic updates and tried to update your software via the automatic software update mechanism you may have seen a warning about the downloaded software installer not being signed by Software Verify. This article is going to explain why you are shown this error message and what you can do about it.</p>
<h1>What does it look like?</h1>
<p>The warning message looks like this:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12535" src="https://www.softwareverify.com/wp-content/uploads/2024/02/MissingDigitalSignatureWarning.png" alt="Missing digital signature warning dialog, shown during software update." width="406" height="180" srcset="https://www.softwareverify.com/wp-content/uploads/2024/02/MissingDigitalSignatureWarning.png 406w, https://www.softwareverify.com/wp-content/uploads/2024/02/MissingDigitalSignatureWarning-300x133.png 300w" sizes="auto, (max-width: 406px) 100vw, 406px" /></p>
<h2>Why does this message get shown?</h2>
<p>This message is shown because although the software installer is signed by Software Verify, the code signing certificate has changed, and our checks for the new code signing certificate fail because the certificate contains slightly different information compared to the previous certificate.</p>
<p>Some history: After a security breach where some code signing keys were stolen from <a href="https://www.bleepingcomputer.com/news/security/malware-now-using-nvidias-stolen-code-signing-certificates/">nVidia</a> and <a href="https://www.cybersecuritydive.com/news/GitHub-breach-code-signing-certificates/641725/">Github</a> (and others, no doubt) the people that oversee code signing decided that the new regime for code signing would be different. No longer would you be able to purchase a code signing certificate for about $100, over the internet, then have the certificate on your own machines. The new regime is that you need to code sign via an online service, or purchase a USB token that holds your code signing certificate securely. This would prevent certificates from being stolen.</p>
<p>The USB token needs to be present to perform any code signing. It&#8217;s not a USB stick that you can read, so although you own the USB token and the certificate it holds, you can&#8217;t directly access the certificate. The USB token comes with some software that presents a password protected gateway between you and signing, and will lock itself forever if you present a bad password 10 times.</p>
<h2>Why didn&#8217;t we test with the old certificate and the new certificate?</h2>
<p>Our code signing certificate expired on 26 Jan 2024. We started the process of obtaining a USB token code signing certificate months ago. This process is time consuming, requires 3rd parties to vouch for our legitimacy, and costs about 20 times as much the previous method. Progress through the various stages of vetting and the releasing the certificate is, er, opaque. You have no idea what is happening, unless you ask, and even then you may not get a useful answer. You just have to wait. Not ideal :-).</p>
<p>We only received our USB token 3 days prior to the old code signing certificate expiring. We didn&#8217;t have enough time to test the new USB token, understand the differences in how the new digitial signatures differed from the previous digitial signatures and get a new software release out that would know the differences and not display the warning message above.</p>
<h2>What can you do to resolve this?</h2>
<p>Login to your user account at software verify (look at a recent software update email for details) and download the software from there.</p>
<p>Once installed you can start using software updates again as the new version knows what the new digital signatures look like.</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.softwareverify.com/blog/potential-misleading-digitial-signature-warning-with-automatic-updates/">Potential misleading digitial signature warning with automatic updates</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/potential-misleading-digitial-signature-warning-with-automatic-updates/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to build all configurations of a Visual Studio project from the command line?</title>
		<link>https://www.softwareverify.com/blog/how-do-i-build-all-configurations-of-a-project-from-the-command-line/</link>
					<comments>https://www.softwareverify.com/blog/how-do-i-build-all-configurations-of-a-project-from-the-command-line/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Fri, 24 Nov 2023 14:27:41 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12417</guid>

					<description><![CDATA[<p>Automating the building of a Visual Studio project can save significant time and reduce errors, especially when dealing with large projects or frequent updates. One [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/how-do-i-build-all-configurations-of-a-project-from-the-command-line/">How to build all configurations of a Visual Studio project from the command line?</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div data-pm-slice="2 2 []">
<p>Automating the building of a Visual Studio project can save significant time and reduce errors, especially when dealing with large projects or frequent updates. One common approach is to use a build command from the command prompt on Windows, which allows you to build project files directly without opening the Visual Studio IDE.</p>
<p>Manually opening Visual Studio and building each project or solution is tedious and inefficient. </p>
<p>Visual Studio Project Builder is a tool designed to help automate these tasks. Additionally, build commands can be executed from the command prompt or batch files on Windows, making it easier to integrate automated builds into your development process.</p>
</div>
<h2>The problem</h2>
<p>I needed an easy way to automate the building of a Visual Studio project from the command line.</p>
<p>It needed to work regardless of which Visual Studio the project file was from. Visual Studio 2022 through Visual Studio 6. That&#8217;s three different project file formats (.dsp, .vcproj and .vcxproj) and three different Visual Studio command line styles (msdev.exe, devenv.exe and msbuild.exe).</p>
<p>We have <a href="https://www.softwareverify.com/product/visual-studio-project-builder/">Visual Studio Project Builder</a>, which is an interactive tool that can build large collections of Visual Studio <a href="https://www.softwareverify.com/blog/improving-how-we-build-projects-and-solutions/">projects and solutions</a>, but I couldn&#8217;t use it to automate this task because I needed to interact with the user interface a few times during the process.</p>
<p>A few months back we upgraded Visual Studio Project Builder to <a href="https://www.softwareverify.com/blog/how-do-i-build-all-projects-in-a-solution-from-the-command-line/">build all projects in a solution from the command line</a>. I thought adding the same functionality to handle projects would be a good idea.</p>
<p>Time for an upgrade for Visual Studio Project Builder.</p>
<h2>/buildProject</h2>
<p>To build a project with Visual Studio Project Builder we&#8217;ve added the <span style="font-family: 'courier new', courier, monospace;"><strong>/buildProject</strong></span> option.</p>
<p>Specify <strong><span style="font-family: 'courier new', courier, monospace;">/buildProject path-to-project.vcxproj</span></strong>, and use quotes to surround any path containing spaces.</p>
<p>Examples:</p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">visualStudioProjectBuilder.exe /vcxproj /buildProject e:\om\c\testApp\testApp.vcxproj</span></p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">visualStudioProjectBuilder.exe /vcxproj /buildProject &#8220;e:\om\c\dev workspace\testApp\testApp.vcxproj&#8221;</span></p>
<p>The Visual Studio Project Builder user interface is shown during the build process so that you can see the progress of the build.</p>
<p>There is no need for you to interact with the user interface, it will close automatically at the end of the build.</p>
<h2>Settings</h2>
<p>You&#8217;re going to want to use the appropriate settings file when building your projects. Load the settings file with <span style="font-family: 'courier new', courier, monospace;"><strong>/loadSettings</strong></span>.</p>
<p>Specify <strong><span style="font-family: 'courier new', courier, monospace;">/loadSettings path-to-settings.vspbs</span></strong>, and use quotes to surround any path containing spaces.</p>
<p>Examples:</p>
<div style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">/loadSettings c:\mysettings\settings.vspbs</span></div>
<div> </div>
<div style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">/loadSettings &#8220;e:\my settings\settings.vspbs&#8221;</span></div>
<div> </div>
<p>Alternatively, you can use<strong><span style="font-family: 'courier new', courier, monospace;">/resetSettings</span></strong> to use the default settings to build the solution.</p>
<p>You can also specify the same project file types as the project. Choose one of:</p>
<p><span style="padding-left: 40px; font-family: 'courier new', courier, monospace;">/vcxproj</span><br />
<span style="padding-left: 40px; font-family: 'courier new', courier, monospace;">/vcproj</span><br />
<span style="padding-left: 40px; font-family: 'courier new', courier, monospace;">/dsp</span><br />
<span style="padding-left: 40px; font-family: 'courier new', courier, monospace;">/csproj</span><br />
<span style="padding-left: 40px; font-family: 'courier new', courier, monospace;">/fsproj</span><br />
<span style="padding-left: 40px; font-family: 'courier new', courier, monospace;">/vbproj</span><br />
<span style="padding-left: 40px; font-family: 'courier new', courier, monospace;">/vjsproj</span></p>
<h2>Batch file usage</h2>
<p>To work with batch files you&#8217;ll need to specify the type of project file and the project file name, plus any optional arguments.</p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">/vxproj</span> Use a modern Visual Studio file format</p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">/buildproject path-to-project-name</span> load project file</p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">/wait</span> instruct the batch file to wait until Visual Studio Project Builder has closed</p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">/resetSettings</span> resets the settings to default</p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">/loadSettings &#8220;e:\my settings\settings.vspbs&#8221;</span> load settings from a file</p>
<p><strong>Example 1:</strong></p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">start /wait &#8220;Build TestApp&#8221; &#8220;C:\Program Files (x86)\Software Verify\Visual Studio Project Builder\visualStudioProjectBuilder.exe&#8221; /resetSettings /vcxproj /buildProject &#8220;e:\om\c\testApp\testApp.vcxproj&#8221;</span></p>
<p>This line in the batch file does this:</p>
<ul>
<li>starts Visual Studio Project Builder</li>
<li>resets the settings to the default <span style="font-family: 'courier new', courier, monospace;">/resetSettings</span></li>
<li>loads the Visual Studio project <span style="font-family: 'courier new', courier, monospace;">e:\om\c\testApp\testApp.vcxproj</span> (you can specify other project types)</li>
<li>builds all configurations of the project (which configurations are controlled by the settings &#8211; you can change this by using <span style="font-family: 'courier new', courier, monospace;">/loadSettings</span>)</li>
<li>closes Visual Studio Project Builder</li>
<li>the batch file waits for Visual Studio Project Builder before executing the next statement in the batch file <span style="font-family: 'courier new', courier, monospace;">/wait</span></li>
</ul>
<p><strong>Example 2:</strong></p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">start /wait &#8220;Build TestApp&#8221; &#8220;C:\Program Files (x86)\Software Verify\Visual Studio Project Builder\visualStudioProjectBuilder.exe&#8221; /loadSettings &#8220;e:\my settings\settings.vspbs&#8221; /buildProject &#8220;e:\om\c\testApp\testApp.vcxproj&#8221;</span></p>
<p>This line in the batch file does this:</p>
<ul>
<li>starts Visual Studio Project Builder</li>
<li>loads settings from <span style="font-family: 'courier new', courier, monospace;">e:\my settings\settings.vspbs</span></li>
<li>loads the Visual Studio project <span style="font-family: 'courier new', courier, monospace;">e:\om\c\testApp\testApp.vcxproj</span> </li>
<li>builds all configurations of the project (which configurations are controlled by the settings &#8211; you can change this by using <span style="font-family: 'courier new', courier, monospace;">/loadSettings</span>)</li>
<li>closes Visual Studio Project Builder</li>
<li>the batch file waits for Visual Studio Project Builder before executing the next statement in the batch file<span style="font-family: 'courier new', courier, monospace;">/wait</span></li>
</ul>
<p>&nbsp;</p>
<p>The post <a href="https://www.softwareverify.com/blog/how-do-i-build-all-configurations-of-a-project-from-the-command-line/">How to build all configurations of a Visual Studio project from the command line?</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/how-do-i-build-all-configurations-of-a-project-from-the-command-line/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Loading Validator into a process</title>
		<link>https://www.softwareverify.com/blog/loading-validator-into-a-process/</link>
					<comments>https://www.softwareverify.com/blog/loading-validator-into-a-process/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Wed, 25 Oct 2023 15:23:01 +0000</pubDate>
				<category><![CDATA[Coverage]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Flow Tracing]]></category>
		<category><![CDATA[Memory]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Thread]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12157</guid>

					<description><![CDATA[<p>Everything written here applies to all Validators: Bug, Coverage, Memory, Performance and Thread. There are many ways to start collecting data with a Validator: Launch, [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/loading-validator-into-a-process/">Loading Validator into a process</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Everything written here applies to all Validators: Bug, Coverage, Memory, Performance and Thread.</p>
<p>There are many ways to start collecting data with a Validator: Launch, Inject, Wait, Service, IIS, WDS.</p>
<p>But sometimes the methods we&#8217;ve provided won&#8217;t work because the scenario you&#8217;re trying to track is too complex for the GUI driven options we&#8217;ve provided.</p>
<p>So, in that scenario how do you detect memory leaks, or collect code coverage, etc?</p>
<h2>API</h2>
<p>This is where the API comes in handy, and in particular a convenience function we&#8217;ve written to make life easy.</p>
<p>If you look in the API subdirectory in your Validator&#8217;s install directory you find two files:</p>
<p style="padding-left: 40px;"><span style="font-family: 'courier new', courier, monospace;">loadValidatorIntoAnApplication.c</span><br />
<span style="font-family: 'courier new', courier, monospace;">loadValidatorIntoAnApplication.h</span></p>
<h2>Building a .exe</h2>
<ol>
<li>Add both files to the project that builds the .exe you want to monitor.</li>
<li>For <span style="font-family: 'courier new', courier, monospace;">loadValidatorIntoAnApplication.c </span>you&#8217;ll need to disable precompiled headers.
<ol>
<li>Right click on <span style="font-family: 'courier new', courier, monospace;">loadValidatorIntoAnApplication.c </span> and choose Properties&#8230;</li>
<li>Change the Configuration combo to <strong>All Configurations</strong>.</li>
<li>Expand C/C++ then choose <strong>Precompiled Headers</strong>.</li>
<li>On the right hand side next to <strong>Precompiled Header</strong> change this to <strong>Not Using Precompiled Headers</strong>.</li>
<li>Click <strong>OK</strong></li>
</ol>
</li>
<li>Add <span style="font-family: 'courier new', courier, monospace;">#include &#8220;loadValidatorIntoAnApplication.h&#8221;</span> to the file that contains <span style="font-family: 'courier new', courier, monospace;">main()</span>.</li>
<li>In the <span style="font-family: 'courier new', courier, monospace;">main()</span> function, add a call to <span style="font-family: 'courier new', courier, monospace;">loadValidatorIntoApplication();</span> as the first thing that <span style="font-family: 'courier new', courier, monospace;">main()</span> does.</li>
</ol>
<h2>Building a .dll</h2>
<p><em>If you are building .exe and .dll used by the .exe, ignore this section, follow the instructions for Building a .exe.</em></p>
<ol>
<li>Add both files to the project that builds the .dll you want to monitor. Ideally this should be the first DLL of yours that gets called (this assumes you are building more than one DLL).</li>
<li>For <span style="font-family: 'courier new', courier, monospace;">loadValidatorIntoAnApplication.c </span>you&#8217;ll need to disable precompiled headers.
<ol>
<li>Right click on <span style="font-family: 'courier new', courier, monospace;">loadValidatorIntoAnApplication.c </span> and choose Properties&#8230;</li>
<li>Change the Configuration combo to <strong>All Configurations</strong>.</li>
<li>Expand C/C++ then choose <strong>Precompiled Headers</strong>.</li>
<li>On the right hand side next to <strong>Precompiled Header</strong> change this to <strong>Not Using Precompiled Headers</strong>.</li>
<li>Click <strong>OK</strong></li>
</ol>
</li>
<li>Add <span style="font-family: 'courier new', courier, monospace;">#include &#8220;loadValidatorIntoAnApplication.h&#8221;</span> to the file that contains the first function of your DLL that will be called.</li>
<li>In the first function of your DLL that will be called, add a call to <span style="font-family: 'courier new', courier, monospace;">loadValidatorIntoApplication();</span> as the first thing that function does.</li>
<li>If you don&#8217;t know which function in your DLL will be called first, add the function call to <span style="font-family: 'courier new', courier, monospace;">DllMain()</span> when <span style="font-family: 'courier new', courier, monospace;">(fdwReason == DLL_PROCESS_ATTACH)</span>.
<p>We don&#8217;t recommend this approach because Microsoft state that doing complex work inside <a href="https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain">DllMain()</a> can lead to undefined behaviour. Our experience is that starting Validators from here usually works, but that could change with future operating system releases.</p>
<pre>#include "..\..\..\..\coverageValidator\API\loadValidatorIntoAnApplication.h"

BOOL APIENTRY DllMain(HMODULE   hModule,
                      DWORD     ul_reason_for_call,
                      LPVOID    lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        loadValidatorIntoApplication();
        break;

    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
        break;

    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
</pre>
</li>
</ol>
<h2>Usage</h2>
<p><strong>If Validator is installed on your computer</strong></p>
<p>If Validator is running, when you start your .exe (or load your DLL and call functions in it) it will automatically communicate with the Validator GUI and start reporting memory leaks, or collecting code coverage, etc.</p>
<p>If Validator is not running, it will be started automatically.</p>
<p><strong>If Validator is not installed on your computer</strong></p>
<p>If Validator is not installed on the computer, nothing happens. This allows you to leave this code in your product because you know your customers will never have Validator on their machine.</p>
<h2>Dependencies</h2>
<p>There are no DLL dependencies.</p>
<p>Once you&#8217;ve built your .exe/.dll with the included code you can deploy your .exe/.dll anywhere.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.softwareverify.com/blog/loading-validator-into-a-process/">Loading Validator into a process</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/loading-validator-into-a-process/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
