What’s new with Thread Validator

By , December 10, 2020 6:27 pm

There are some changes coming to Thread Validator.

I’m going to describe the various changes and the reasons behind them.

Name Change

The first one is the name change. C++ Thread Validator becomes Thread Validator.

This change is to keep in line with our other tools not having language specific prefixes.

New UX Theme

A new UX theme which is has less visual clutter and is calmer to look at has been introduced. We’ve written about that in New UX Theme.


x64 and x86 support

C++ Thread Validator shipped in two versions, a 32 bit version and a 64 bit version that could also process 32 bit executables.

Thread Validator ships in a 64 bit version that can also process 32 bit executables. On a 32 bit machine the 32 bit version installs, on a 64 bit machine both 64 bit and 32 bit versions install, because occasionally there is a 32 bit native bug that you only deal with from the 32 bit version of the tool.

The reasons for this change are

  • All our other tools ship in versions that support both 64 bit and 32 bit executables. Thread Validator should do the same.
  • 64 processors are the dominant processors in the market. We should support these by default.

Availability

These changes to Thread Validator will be available after 13 December 2020.

What’s new with Performance Validator

By , December 10, 2020 6:26 pm

There are many changes coming to Performance Validator.

I’m going to describe the various changes and the reasons behind them.

Name Change

The first one is the name change. C++ Performance Validator becomes Performance Validator.

Because Performance Validator will be capable of handling multiple technologies and languages having language specific designators prefixing Performance Validator doesn’t make any sense.

New UX Theme

A new UX theme which is has less visual clutter and is calmer to look at has been introduced. We’ve written about that in New UX Theme.


.Net Support

Performance Validator now supports .Net languages. C#, VB.Net, C++.Net, etc.

.Net Performance Validator is discontinued, all of it’s functionality moving into Performance Validator.

x64 and x86 support

C++ Performance Validator shipped in two versions, a 32 bit version and a 64 bit version that could also process 32 bit executables.

Performance Validator ships in a 64 bit version that can also process 32 bit executables. On a 32 bit machine the 32 bit version installs, on a 64 bit machine both 64 bit and 32 bit versions install, because occasionally there is a 32 bit native bug that you only deal with from the 32 bit version of the tool.

The reasons for this change are

  • .Net applications can be built in 32 bit, 64 bit, and Any CPU versions. An Any CPU version launched on a 64 bit machine will run as 64 bit. To provide full .Net support we couldn’t support Any CPU on 64 bit from 32 bit Performance Validator. The sensible option is to only support Performance Validator in a form that can support both 32 bit and 64 bit architectures.
  • 64 processors are the dominant processors in the market. We should support these by default.

New menu items

To support the new .Net functionality there are some additional launch options for working with ASP.Net applications (IIS and Web Development Server) as well as .Net applications and .Net services.


Launch ASP.Net application using IIS.


Launch ASP.Net application using Web Development Server.


New settings options

The settings dialog has two new panels to allow you to configure .Net Function Inlining and .Net Function Caching. The defaults are the values that an application would normally run with.

.Net Function Inlining


.Net Function Caching


New launch option

With the ability to process both native and .Net applications and mixed mode applications comes the desire to sometimes restrict performance profiling to just native code, or just .Net code, or to allow any code (mixed mode) to be profiled. To handle this we’ve added a simple combo dropdown on the various launch dialogs that allows you to choose how performance profiling is handled at a very high level.


Availability

These changes to Performance Validator will be available after 13 December 2020.

What’s new with Memory Validator

By , December 10, 2020 6:26 pm

There are many changes coming to Memory Validator.

I’m going to describe the various changes and the reasons behind them.

Name Change

The first one is the name change. C++ Memory Validator becomes Memory Validator.

Because Memory Validator will be capable of handling multiple technologies and languages having language specific designators prefixing Memory Validator doesn’t make any sense.

New UX Theme

A new UX theme which is has less visual clutter and is calmer to look at has been introduced. We’ve written about that in New UX Theme.


.Net Support

Memory Validator now supports .Net languages. C#, VB.Net, C++.Net, etc.

.Net Memory Validator is discontinued, all of it’s functionality moving into Memory Validator.

x64 and x86 support

C++ Memory Validator shipped in two versions, a 32 bit version and a 64 bit version that could also process 32 bit executables.

Memory Validator ships in a 64 bit version that can also process 32 bit executables. On a 32 bit machine the 32 bit version installs, on a 64 bit machine both 64 bit and 32 bit versions install, because occasionally there is a 32 bit native bug that you only deal with from the 32 bit version of the tool.

The reasons for this change are

  • .Net applications can be built in 32 bit, 64 bit, and Any CPU versions. An Any CPU version launched on a 64 bit machine will run as 64 bit. To provide full .Net support we couldn’t support Any CPU on 64 bit from 32 bit Memory Validator. The sensible option is to only support Memory Validator in a form that can support both 32 bit and 64 bit architectures.
  • 64 processors are the dominant processors in the market. We should support these by default.

New menu items

To support the new .Net functionality there are some additional launch options for working with ASP.Net applications (IIS and Web Development Server) as well as .Net applications and .Net services.


Launch ASP.Net application using IIS.


Launch ASP.Net application using Web Development Server.


New settings options

The settings dialog has four new panels to allow you to configure what types of .Net data are collected, whether to enable stale .Net object detection, if .Net heap dumps should be collected, and how and when .Net memory snapshots should be made.

.Net Collect


.Net Stale Object Detection


.Net Heap Dump


.Net Snapshots


New launch option

With the ability to process both native and .Net applications and mixed mode applications comes the desire to sometimes restrict memory monitoring to just native code, or just .Net code, or to allow any code (mixed mode) to be monitored. To handle this we’ve added a simple combo dropdown on the various launch dialogs that allows you to choose how memory monitoring is handled at a very high level.


New Summary Display


The summary display provides panels for a particular summary topic with key statistics for that topic displayed in the panel. Panels can display bar graphs, circular graphs and timeline graphs as well as data in table format. Most summaries allow you to click on a data item and be taken to a main tab for the data that was clicked on. This allows the summary display to function as a jumping off point to explore data throughout Memory Validator.

New Memory tab

The new memory tab performs the same function as the Memory tab in previous versions of Memory Validator, but now it contains two sub-tabs. One for viewing native allocations (memory and handles), and one for viewing .Net allocations (memory and handles).

New Statistics tab

The Statistics tab is where all the main statistics data is grouped together. Previously this data was in 3 main tabs: Types, Sizes and Locations. Those 3 tabs are now sub-tabs under the statistics tabs. They are joined by two .Net specific tabs: Generations and Ages, which report information about which generation has how many objects and what ages given objects are. The Ages tab can also report information about stale objects if that functionality has been turned on (off by default as CPU intensive).


New .Net tab

A new .Net tab is where you can find 3 new sub-tabs dedicated to understanding .Net specific memory behaviour. The three sub-tabs are .Net Snapshots, .Net Heap Dumps and .Net Leak Analysis.

New Snapshots tab

The Snapshots tab allows you to take memory snapshots and compare them to other memory snapshots creating memory comparisons. Both snapshots and comparisons can be viewed to identify the location where an object was allocated. You can also use the context menu to then jump to that object in a heap dump reference graph.


New Heap Dumps tab

The Heap Dump tab allows you to view heap dumps provided when a garbage collection takes place. Using the reference graph you can see which objects hold a reference to an object, and which objects an object is referencing. Plenty of options are provided to allow you to restrict the amount of data to wade through (so that you don’t end up with a graph full objects you didn’t build – from 3rd party software).


New .Net Leak Analysis tab

The Leak Analysis tab provides you with a powerful query functionality that allows to query the .Net allocation data to find objects that may be leaked, loitering unused in memory due to references that should have been set to null. We provide many predefined queries, but you can easily build your own queries. Combine with stale object detection data for even more power.


New Analysis tab

The old Analysis tab has been renamed Query and is now a sub-tab of the new Analysis tab. This sub-tab is joined by previous main tabs Coverage, Hotspots, Pages and Virtual.

The Hotspots tab has been updated to include hotspots for .Net memory and .Net handles. The hotspots tab has been moved to a sub-tab on the main Analysis tab.

Timeline updates

The Timeline tab has been updated to include data for .Net memory, .Net handles and .Net all allocations to provide an equivalent to the native timeline views.

Availability

These changes to Memory Validator will be available after 13 December 2020.

What’s new with Coverage Validator

By , December 10, 2020 6:26 pm

There are many changes coming to Coverage Validator.

I’m going to describe the various changes and the reasons behind them.

Name Change

The first one is the name change. C++ Coverage Validator becomes Coverage Validator.

Because Coverage Validator will be capable of handling multiple technologies and languages having language specific designators prefixing Coverage Validator doesn’t make any sense.

New UX Theme

A new UX theme which is has less visual clutter and is calmer to look at has been introduced. We’ve written about that in New UX Theme.


.Net Support

Coverage Validator now supports .Net languages. C#, VB.Net, C++.Net, etc.

.Net Coverage Validator is discontinued, all of it’s functionality moving into Coverage Validator.

x64 and x86 support

C++ Coverage Validator shipped in two versions, a 32 bit version and a 64 bit version that could also process 32 bit executables.

Coverage Validator ships in a 64 bit version that can also process 32 bit executables. On a 32 bit machine the 32 bit version installs, on a 64 bit machine both 64 bit and 32 bit versions install, because occasionally there is a 32 bit native bug that you only deal with from the 32 bit version of the tool.

The reasons for this change are

  • .Net applications can be built in 32 bit, 64 bit, and Any CPU versions. An Any CPU version launched on a 64 bit machine will run as 64 bit. To provide full .Net support we couldn’t support Any CPU on 64 bit from 32 bit Coverage Validator. The sensible option is to only support Coverage Validator in a form that can support both 32 bit and 64 bit architectures.
  • 64 processors are the dominant processors in the market. We should support these by default.

New menu items

To support the new .Net functionality there are some additional launch options for working with ASP.Net applications (IIS and Web Development Server) as well as .Net applications and .Net services.


Launch ASP.Net application using IIS.


Launch ASP.Net application using Web Development Server.


New settings options

The settings dialog has two new panels to allow you to configure .Net Function Inlining and .Net Function Caching. The defaults are the values that an application would normally run with.

.Net Function Inlining


.Net Function Caching


New launch option

With the ability to process both native and .Net applications and mixed mode applications comes the desire to sometimes restrict code coverage to just native code, or just .Net code, or to allow any code (mixed mode) to be covered. To handle this we’ve added a simple combo dropdown on the various launch dialogs that allows you to choose how code coverage is handled at a very high level.


Availability

These changes to Coverage Validator will be available after 13 December 2020.

New UX Theme

By , December 8, 2020 11:49 am

We’ve been working on a new, calmer UX Theme for a while.

The aim is to reduce the number of lines, have less visual clutter, better demarcation of boundaries, consistent colour use across all tools, and to make everything just a bit simpler and calmer to look at.

The best way to show you these changes to show before and after images of each change.

Dialog Titles

Before: Sections are indicated by text with a horizontal line next to it.


After: Sections are indicated by bold text in Software Verify blue with no horizontal line.


Settings grids

Before: Vertical and horizontal grid lines are part of the display.


After: Vertical and horizontal grid lines are minimised with the boundaries between adjacent lines indicated by a subtle change of background colour.


Data grids

Before: Vertical and horizontal grid lines are part of the display.


After: Horizontal grid lines are minimised with the boundaries between adjacent lines indicated by a subtle change of background colour. Vertical grid lines are present, but very subtle so as not to intrude on the display.


Grid highlighting

Before: There was no automatic grid highlighting.


After: When you move the mouse over a grid the line under the mouse automatically highlights in light blue. This can be very useful on wide grids with many columns.


The grid highlighting functionality does not change which items are selected in the grid. It is purely a visual aid. The grid highlighting works for both data grids and settings grids.

Tab Headings

Before: Tabs were displayed with the current tab in bold.


After: Tabs are displayed with all tabs in Software Verify blue and the current tab is bold with the orange highlight colour.


Graphics – Circles

Before: Circles were displayed with outlines and pie section separators.


After: Circles are displayed without outlines and with no pie section separators.


Graphics – Bars

Before: Bars were displayed with outlines.


After: Bars are displayed without outlines.


Splitter Windows

Before: The splitter and the edges of the window were highlighted.

After: The splitter is highlighted. The edges are not highlighted.

Toolbar and menu icons

Before: Our previous icon set was 3D and looked a bit tired.


After: The new icon set is flat and uses the Software Verify colour palette.


Conclusion

These changes in isolation probably don’t look like much, but when you see them all together it makes for a more pleasant experience. The effect is magnified when you’re looking at a lot of data – having less clutter. It’s a subtle but important thing.

These changes will be rolled out across all our tools, both free and commercial, in the weeks following 8 December 2020.

Customers that have purchased tools and that have valid software maintenance will be emailed when software updates containing these changes are available for them to download.

Changes to how we display data

By , June 12, 2020 11:59 am

We’ve changed the display of data on all of our tree controls that are used to display callstacks and call trees.

The old method of display, everything was displayed in black text at normal font weight.

The new method of display, different components of the text are displayed in their own colour, with optional bold, italic, underline or strikethrough, with an optional change in font face. In practice, at present we’re only changing the display colour and turning bold on/off.

We’re using this new display technology to leave some items neutral, emphasise some items and de-emphasise other items. This change has made quite a difference in readability of the display. Right now there is no ability for the user of the software to edit these settings to change the prioritisation and colour scheme we’ve chosen. We’ll provide this capability in a future release.

I’m going to show some before and after images so that you can see the difference for each tool.

C++ Memory Validator

For C++ Memory Validator, we’ve changed both function and filename to be displayed in bold. Type, thread name, timestamp, module name, and symbol name are displayed in different colours. Address is displayed in a de-emphasised colour.

Before


After


Before


After


.Net Memory Validator

For .Net Memory Validator, we’ve changed both function and filename to be displayed in bold. Age, Generation, thread name, timestamp, module name, and symbol name are displayed in different colours. Address is displayed in a de-emphasised colour.

Before


After


Before


After


Thread Validator

For Thread Validator, we’ve changed both function and filename to be displayed in bold. Thread name, timestamp, module name, and symbol name are displayed in different colours.

Before


After


Before


After


Performance Validator

For Performance Validator, we’ve changed both function and filename to be displayed in bold. Module name, and symbol name are displayed in different colours.

Before


After


Coverage Validator

For Coverage Validator, the branches, files and directory displays have had a few tweaks to de-emphasis address information.

Before

After

Bug Validator

For Bug Validator, we’ve re-ordered the display information so that the symbol comes before the filename. Both function and filename are displayed in bold. Timestamp, thread name, module name, and symbol name are displayed in different colours.

Before

After

Memory leak in CPngImage

By , June 1, 2020 9:37 am

A memory leak in a surprising place

We’ve recently been doing some work switching our resources in our programs from BMP (using CBitmap) to PNG (using CPngImage).

At some point we got around to dog-fooding, which we do with our tools all the time, and we were surprised to see memory leaks (in the form of HGLOBAL handles) in our tools being reported by C++ Memory Validator.


We took a look and found they were coming from CPngImage::LoadFromBuffer(). Here’s the code, with the leaking lines highlighted.

BOOL CPngImage::LoadFromBuffer(LPBYTE lpBuffer, UINT uiSize)
{
        ASSERT(lpBuffer != NULL);

        HGLOBAL hRes = ::GlobalAlloc(GMEM_MOVEABLE, uiSize); // this line leaks
        if (hRes == NULL)
        {
                return FALSE;
        }

        IStream* pStream = NULL;
        LPVOID lpResBuffer = ::GlobalLock(hRes);             // this line leaks
        ASSERT (lpResBuffer != NULL);

        memcpy(lpResBuffer, lpBuffer, uiSize);

        HRESULT hResult = ::CreateStreamOnHGlobal(hRes, FALSE, &pStream);

        if (hResult != S_OK)
        {
                return FALSE;
        }

        if (CMFCToolBarImages::m_bMultiThreaded)
        {
                CMFCToolBarImages::m_CriticalSection.Lock();
        }

        if (m_pImage == NULL)
        {
                m_pImage = new CImage;
                ENSURE(m_pImage != NULL);
        }

        m_pImage->Load(pStream);
        pStream->Release();

        BOOL bRes = Attach(m_pImage->Detach());

        if (CMFCToolBarImages::m_bMultiThreaded)
        {
                CMFCToolBarImages::m_CriticalSection.Unlock();
        }

        return bRes;
}

Verifying the memory leak

At first we thought C++ Memory Validator might have made a mistake, as it seemed unlikely that such a well used class would contain a mistake like a memory leak.

To check if this was correct memory leak report or a FALSE positive we created a test program where we can repeatedly create and destroy images in rapid succession. If the leak is real the toy program will soon fail to allocate memory. If the leak is a false positive by C++ Memory Validator, the toy program will run forever with no problems. The toy program demonstrated the leak is real – after just over 65,000 loads of an image with CPngImage, all GlobalAlloc() allocations fail.

The test program allows you to repeatedly load a BMP, a PNG into CPngImage and a PNG into an svlPngImage. The image is destroyed after loading. You can specify how many times to perform the load, 1, 10, 100, 1000, 10000, 64K and 100,000 times.


We have verified that his memory leak is present in all versions of CPngImage that ship with all versions of Visual Studio (up to and including VS2019, we haven’t looked at VS2021 yet).

Fixing the memory leak

The fix is to add two lines just before the return bRes; statement.

        ::GlobalUnlock(hRes);
        ::GlobalFree(hRes);

Unfortunately CPngImage loads it data from methods that are not virtual, so we couldn’t replace them in the implementation. We created a drop in replacement for CPngImage called svlPngImage. It’s identical to the CPngImage class with the exception that the CMFCToolBarImages calls are commented out, and the two additional lines to prevent the memory leak are added. If you’d like to use svlPngImage the source code for this drop in replacement is in the download.

Test Program Source Code

You can download the test program source code and project files.

Update, after response from Microsoft

I was surprised when I got a reply saying this couldn’t happen because the second parameter to ::CreateStreamOnHGlobal() was TRUE. I searched my machine again, and it was FALSE. I then searched a different machine and it was TRUE. So most likely this bug did exist (and we’re using the version of Visual Studio that has it) but has been fixed in a more recent service pack. My claim that the bug was in all versions of Visual Studio was incorrect because I was checking for the absence of the memory freeing calls without checking the value passed to ::CreateStreamOnHGlobal() was FALSE. The drop in replacement class is still valid.

If you’re using CPngImage, check CPngImage::LoadFromBuffer() and if the second parameter passed to ::CreateStreamOnHGlobal() is FALSE, use our svlPngImage class instead. Otherwise carry on as you are.

Update 2, after further response from Microsoft

Microsoft has modified this function to improve the error handling to fix a memory leak if ::CreateStreamOnHGlobal() fails, in response to this bug report, which prompted them to reexamine the function. Ironic in that the report I made, although demonstrating a real bug, that bug had already been fixed, but it still prompted a fresh look at the function behaviour.

Detecting memory leaks in ISAPI extensions

By , April 21, 2020 11:51 am

Three weeks ago I wrote about how to setup IIS for use with ISAPI extensions.

Today I’m going to show you how easy it is to monitor memory and handle allocations in IIS, and use that information to detect any memory and handle leaks that may be present in your ISAPI extension.

IIS is a very secure Windows service. The account security for IIS mean that it can’t access most parts of the Windows filesystem or even Windows objects. CGI and ISAPI extensions will only execute if you’ve configured IIS properly (see the above linked article for details). You can’t launch IIS from a tool like Memory Validator, and you can’t inject into IIS from a tool like Memory Validator because of the security constraints. That leaves you the option of using an API to interact with IIS from your tool of choice.

But I don’t want to use an API!

“But I don’t want to use an API” I hear you say. You’re concerned about having to build multiple versions of your ISAPI. One for use with Memory Validator and one for production. That’s a valid concern, but it’s not the case. You can just build one version of your ISAPI that uses Memory Validator and use that. If you haven’t done “Monitor ISAPI…” from the Launch menu prior to loading your ISAPI the Memory Validator dlls won’t be loaded. There is no dependency on Software Verify DLLs, you can ship your DLL without any need to ship the Memory Validator DLLs.

But should you need to examine memory allocation behaviour you can just fire up Memory Validator and get to work without making a special build.

ISAPI API

ISAPI extensions provide 3 APIs for IIS to use:

BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer);

BOOL WINAPI TerminateExtension(DWORD	dwFlags);

DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB);

GetExtensionVersion() is called when the ISAPI is first loaded. We’ll use this to load Memory Validator into IIS.

TerminateExtension() is called when the ISAPI is unloaded. We’ll use this to tell Memory Validator that the work with IIS is done.

HttpExtensionProc() is used to process any requests made to the ISAPI extension.

Memory Validator API

To add the Memory Validator API to the ISAPI we do the following to the ISAPI source code:


  1. Add two header files:

    #include "svlMVStubService.h"
    #include "svlServiceError.h"
    

  2. We add the following code to GetExtensionVersion(). This includes logging success and failure so that we can identify if anything has gone wrong. Without the logging determining failure inside of IIS is very hard (a debugger and a special build of the Memory Validator DLL is required).

        // load Validator here
    
        svlMVStub_setLogFileName(L"C:\\testISAPIWebsite\\svl_MV_log.txt");
        svlMVStub_deleteLogFile();
    
        SVL_SERVICE_ERROR   errCode;
    #ifdef IS6432
        // x86 with x64 GUI
        errCode = svlMVStub_LoadMemoryValidator6432();
    #else   //#ifdef IS6432
        // x86 with x86 GUI
        // x64 with x64 GUI
        errCode = svlMVStub_LoadMemoryValidator();
    #endif   //#ifdef IS6432
        if (errCode != SVL_OK)
        {
            DWORD   lastError;
    
            lastError = GetLastError();
            svlMVStub_writeToLogFileW(L"C++ Memory Validator load failed. \r\n");
            svlMVStub_writeToLogFileLastError(lastError);
            svlMVStub_writeToLogFile(errCode);
    
            svlMVStub_dumpPathToLogFile();
        }
        else
        {
            svlMVStub_writeToLogFileW(L"C++ Memory Validator load success. \r\n");
    
            errCode = svlMVStub_StartMemoryValidatorForIIS();
    	if (errCode != SVL_OK)
    	{
                DWORD   lastError;
    
                lastError = GetLastError();
                svlMVStub_writeToLogFileW(L"Starting C++ Memory Validator failed. \r\n");
                svlMVStub_writeToLogFileLastError(lastError);
                svlMVStub_writeToLogFile(errCode);
    	}
    
            svlMVStub_writeToLogFileW(L"Finished starting C++ Memory Validator\r\n");
        }
    

    You’ll need to edit the location of the logfile to match the name of your website directory.

  3. We add the following code to TerminateExtension().

        // unload Validator here
    
        svlMVStub_UnloadMemoryValidator();
    


Monitoring memory allocations

Start Memory Validator.

From the Launch menu choose the IIS sub menu and then Monitor ISAPI….

The monitor ISAPI dialog is displayed. Any settings from a previous launch are displayed. Edit the settings appropriately.

You need to identify the ISAPI dll that is being processed, the website directory, the IIS process (choose Any IIS if you don’t know or don’t care), the web browser (the default is Microsoft Edge as it seems more tolerant of data format errors than Chrome) and finally the URL you wish to use to test the ISAPI.

Click OK.

Memory Validator copies some DLLs to the directory containing the ISAPI, sets up various variables that will be used inside the IIS process, resets IIS, and launches the web browser to load the specified URL that will load the ISAPI.

When you’ve finished interacting with the ISAPI, you’ll need to stop IIS. Go to the Launch menu, choose the IIS sub menu then Stop IIS.

When IIS has stopped executing Memory Validator displays “Ready” on the status bar, the Memory tab will show any memory leaks and handle leaks that are present.

A short video of this process is shown below.

Conclusion

We’ve completely reworked our ISAPI support so that you have very little to do, just use the API as shown above and launch using the Monitor ISAPI command.

In comparison, here are some instructions for using Boundschecker with IIS. These are out of date and will no longer work. But look how much you have to do manually.

Setting up ISAPI on IIS 10

By , April 3, 2020 11:27 am

Introduction

OK so it’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. I recently had to setup IIS 10 for work 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’t need to spend that much time doing this again!). I’m sharing it so you don’t have to go through this.

There’s an interesting gotcha if you’re developing a 32 bit ISAPI extension. Don’t worry I cover that at the end.

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’s a good starting point for a simple ISAPI extension if you haven’t already written one.

Creating an ISAPI extension: https://www.codeproject.com/Articles/1432/What-is-an-ISAPI-Extension

Installing IIS components

IIS components are installed via the Windows features dialog.

In the Windows 10 search box type “Turn Windows features on and off”, when windows shows you the result that matches press return (or click it).



The feature selection box is displayed. Select the items highlighted red in the image shown below. Click OK.



If you’ve already got partway through configuring IIS Manager and have realised you don’t have all the required components installed that’s OK, just install them and then close IIS Manager and reopen it (I found that if I didn’t do that not all the component parts would show in IIS Manager, making finding say ISAPI and CGI Restrictions impossible.

Configuring IIS Manager

Start Internet Information Services Manager.

Website

First of all we need a website to work with. If you’ve already got one skip the next few lines.

Add a test website. Right click on “Sites” in the left hand menu and choose “Add Website…”

Choose a website name. For example: “test”.

Choose a location for the website. For example: C:\testISAPIWebsite

Change the port number (just for testing) so that it doesn’t conflict with any other sites you have. For example: 81.

Handler Mappings

Select the server node on the left hand side and double click click on Handler Mappings on the right hand size.



The handler mappings are displayed.



Right click in empty space and choose “Edit Feature Permissions…”.

The Edit Feature Permissions dialog is displayed. Enable Read, Script and Execute persmissions. When you select the execute check box you’ll notice the entry for ISAPI dlls is added to the displayed Handler Mappings. Click OK.



ISAPI and CGI Restrictions

Select the server node on the left hand side and double click click on “ISAPI and CGI Restrictions” on the right hand size.

Right click in empty space and choose “Add…”.

Add the path to your ISAPI dll, a description and select the check box so that it is allowed to execute. Click OK.



This will place a web.config in the directory that contains the DLL. It will look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers accessPolicy="Read, Execute, Script">
            <remove name="ISAPI-dll" />
            <add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" scriptProcessor="C:\testISAPIWebsite\validate.dll" resourceType="File" requireAccess="Execute" allowPathInfo="true" preCondition="bitness32" />
        </handlers>
    </system.webServer>
</configuration>

32 bit ISAPI extensions

If your ISAPI is 32 bit you’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 “Advanced Settings…”. Change the “Enable 32-Bit Applications” setting to True.


64 bit ISAPI extensions

If your ISAPI is 64 bit you’ll need to ensure that you haven’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 “Advanced Settings…”. Change the “Enable 32-Bit Applications” setting to False.

Authentication problems

If when trying to view your web pages you get strange error messages, select the server node on the left then go to “Feature Delegation” and turn any entries that are “Read only” to “Read/Write”. Then restart the server (top of the right hand bar).

Note that I’m assuming you’re working on a Dev machine. If you’re working on a production machine you might want to be a bit less cavalier than just turning all settings to Read/Write – work through them one at a time to find out what you need and change only that.

Trying out the website

If we assume your ISAPI is called validate.dll you should be able to test your ISAPI in a browser using http://localhost:81/validate.dll?12345678

The unintended consequence of not paying sick pay

By , March 6, 2020 4:49 pm

Setting the scene

I wrote this several years ago but it never became published. Reading it now it still seems to be valid. Even more so with coronavirus in the news.

Odds are that if you are reading this and you an IT professional this situation doesn’t apply to you. You are either employed in a full time permanent position (you receive sick pay) or you are a contractor (you provide your own sick pay – it’s a risk you take). This article is the result of a discussion with a friend. We are both based in the UK. In your country the legal aspects may be different but the principle remains.

However if you are a part time employee you may not be paid sick pay. I found this out when chatting with a friend of mine about one of their part time jobs (they have several, one main one to provide an income backbone and two others to ring the changes so they don’t do one type of work all the time).

I know this person really well. Conscientious, hard working, honest, caring, won’t accept jobs they can’t do well, etc. The type of person you want working for you. A string of events have happened to them recently that make them doubt their current main employer. First the employer won’t delegate and gets over stressed as a result. This then leads to the employer bad mouthing the staff to other people (which it turns out have been friends of some of the staff and in one case a customer – ooops!). This gets back to the staff and is seriously demoralising, especially when it’s unjustified.

Then recently my friend was ill for about a week. When they received their pay their pay they found out that they had not been paid for the days they took sick. You can imagine how this made them feel – not very valued by their employer. This has caused a lot of upset (and financial harm) to this person.

This raises some interesting questions.


  1. What do you gain/lose by paying sick pay?

  2. What do you gain/lose by not paying sick pay?

I’ve posed the questions in this way because this is surely the reasoning behind choosing not to pay sick pay. That paying it is a cost to be avoided and not paying it saves you money. Let us examine this:

What do you gain/lose by paying sick pay?

There is undoubtedly a risk that some of the people you employ are not going to be as honest as some others. Some put the hours in they are required to do and go home. Some do that and also do more and also do personal development. And some put the time in but take every opportunity to shirk off their work, be lazy and take sick days even when they are not sick.

It’s an unfortunate fact that some people will game the system to their advantage. If they know they’ll get paid for being ‘ill’ while they are really at the local cinema watching the latest flick on the first day of opening then they think that is a risk worth taking and they "pull a sicky"

But on the flip what you gain is loyalty from those staff that don’t fall into that group. They value the fact that you will look after them when they are ill. These people rarely abuse the sick day provision.

What do you gain/lose by not paying sick pay?

So there are pros and cons to paying sick pay. All reasonably obvious. But what about the consequences of not paying sick pay?

Let’s start with the obvious consequence: By not paying sick pay you save money not only by not paying for illegitimate sick day claims, but you also save money when hard working staff are ill too. Ca-Ching! Well, not really as you’ve just demonstrated to the hard working staff that you don’t value them. Pretty stupid move.

Any not so obvious consequences? Yes. If you are not going to be paid when you are sick, how is that any different to unpaid leave? Apart from the chances of dismissal if caught being dishonest, it’s the same. By not paying sick pay you remove any incentive to be honest about why you were not at work (were you ill or you just couldn’t be bothered or you thought tarring and feathering the local tramp was a better idea?).

"I fancy doing some decorating today? I’ll pull a sicky. I won’t get paid, but I will get this annoying job done. Which is more important to me today? My life is, Decorating it is then." And to hell with the business today. Instant holiday. No permission asked.

This one could leave some businesses in the lurch when they find out with no notice that someone isn’t coming in and the only reason is "I’m sick" (but what they don’t know is this person doesn’t care because they know they are not valued).

A lot of businesses employ part time staff. Many of them are businesses that start early in the morning and close late at night, resulting in a day longer than the typical 7.5 or 8 hours. The last thing these businesses need is to find out at 2pm as the second shift starts that a key team player isn’t coming in today. And by not paying sick pay they increase the likelihood of such a situation.

Working ill

The other unintended consequence of not paying sick pay is that people that are ill and should not attend work, may well choose to attend work because they need the money more than they need to stay in bed recovering. This is especially true of people on zero hours contracts and low pay contracts.

Coronavirus is in the news these days, and to stem this pandemic we really need ill people to do the right thing. But the right thing for society is in competition with the right thing for an individual on a low income who probably has negligible savings. They’re going to come to work with their illness as the short term gain for them (pay) outweighs the long term harm to others (some people may get ill). Humans discount future events, so that harm is in the distance and also not to them, as they’re already ill.

This latter scenario is seriously reduced as an outcome if people are paid enough to be able to take time off work when they are ill.

My friend – their choice

I’m not sure what they are going to do. What is clear though that having realised this unintended consequence and how their employer feels about them (despite customer comments to the contrary) their loyalty to the business has evaporated. I wouldn’t be at all surprised to find some unpaid "sick leave" happens to allow my friend to do various things they need to do in their personal life at the expense of the business they would otherwise be working for.

I guess some people are going to read this and think WTF? But the point is this consequence only happens when you have good conscientious staff and then you don’t value them. If they were paid sick pay they wouldn’t feel unvalued or even think of pulling a sicky, let alone an unpaid sicky (which is in this situation the same, but more wilful).

The really sad thing? My friend likes to do a good job. Wants to work where a good job and good attitude is valued. But it seems that for the types of work they do such employers are rare beasts (not like the IT world where to keep staff you have to be a good employer).

I’m not really sure if my words have done justice to what I’m trying to explain here.

Panorama Theme by Themocracy