C#: Recursively Getting Subfolders Whilst Ignoring the Errors that Would Stop Other Traversal Means

So, I’m writing something that is – eventually – meant to scrub the harddrive on IoC (indicators of compromise). The first major problem to solve is the following:

If I have drive ‘C:\’, and I try to enumerate all of the folders under the drive, Directory.EnumerateDirectories (including the recursive search option of all directories), then the first exception that throws stops the iteration – entirely.

This is, I suppose, desired behaviour from a code-provider’s perspective but entirely undesirable from a code consumer’s perspective.

So, how can we get around this? Well, we need a way to “swallow” the exceptions but to carry-on with the folders that we can access but we need to keep processing for this to occur. Instead of nesting foreach ad-infinitum (because we never know how deep or shallow the traversal might be), we would – instead – call the method recursively on itself.

So, it breaks down in the following code:

private static void EnumerateSubfolders(string path)
{
try
{
string[] directories = Directory.EnumerateDirectories(path).ToArray();
foldersList.AddRange(directories);
foreach (string directory in directories)
{
EnumerateSubfolders(directory);
}
}
catch
{
// Dispose of all of the exceptions about access because we can’t do anything about them.
}
}

Note that all we’re doing is going one child-folder deep, adding the results to the list of string of folders and then for each of those, traversing one child-folder deep, again. In this way, even if we hit an exception, we’ve gone one child deep and we stop processing for that child – without it affecting the traversal of the other children; which, while not the idyllic for obtaining all of the folders in Windows, is a far cry better than the entire process stopping on the first exception thrown.

Happy programming! ūüôā

 

 

HttClient: The Myths Behind ‘Using’ on a ReEntrant Object

In developing a solution in Azure to [REDACTED], I discovered a “bug” in HttpClient that seems to be somewhat common knowledge but I figured that I would share it with you, in case you run into the same problems.

This bug surfaced – moreso – because we’re using Azure, than anything else. You see, anything in Azure should be considered multitenancy; meaning that your app is running parallel to – potentially – hundreds of other apps within the infrastructure’s backplane.

So, I was using Parallel.ForEach and .ctor’ing a new HttpClient per thread and making a call to obtain data from a rest endpoint from a unique sub-url; which was entirely dependent on data that I had previously obtained via another rest call. Obscurity is strong with this one, I’m aware.

Every once in a while, I would get the exceptions (by unboxing them): “Only one usage of each socket address (protocol/network/port) is normally permitted: <ipAddressGoesHere>.

In technicality, I was only using one address per HttpClient but there’s a catch/caveat to all of this. Even¬†if you use the ‘using‘ statement, the IDispose interface isn’t immediately called.

The socket would still be in use, even if it were. This is because the socket that the HttpClient uses is put into TIME_WAIT. So, you have an open socket in use to that host and because the host hasn’t closed the socket, if you instantiated all new HttpClients (which used new ephemeral ports), you could potentially run out of ports to consume.

…but, wait, there’s more!‚ĄĘ

The HttpClient is considered reentrant¬†(and this is where our true problem comes in). This means that some (if not all) of your non-disposed of HttpClients could be¬†re-used to try to go what the HttpClient considers a currently in-use object (because the port is still considered open when it’s in TIME_WAIT).

In fact, if we chase down the SocketException –> Win32Exception –> hResult, we can see that this comes from the system as 0x00002740, which is WSAEADDRINUSE.

The solution? Since public static (I think just static, really) instances of HttpClient are considered thread-safe, the singleton model is what we want to go with.

So, instead of instantiating an HttpClient per call, you would instantiate a singleton instance that would be used per-host in your class instance. This allows the HttpClient and it’s port to be re-used (thus, reducing potential ephemeral port exhaustion as a byproduct). And since it appears that Azure re-instantiates your class per run (if you’re using the TimerTrigger, for example), then you create a scenario where the object’s lifetime is bound to your class. (Assuming you call HttpClient.Dispose() before the run completes and the object moves out of scope.)

…but MSDN says to use ‘using’ for IDisposable objects!

Yes, this is true but, again, we have to consider that even though .Dispose()¬†might be called when we leave scope, we have no control over when GC actually comes through and disposes of the object from the Gen1/Gen2 heaps. We also cannot control when the TCP port is¬†actually closed because that’s dependent on the host. So, even if HttpClient.Dispose() is called, you’re still at the whims of the keep-alive configured on the host for the¬†actual port to be closed.

Diagram from the IETF? Diagram from the IETF.

Time_Wait

So, even though it’s been practically beaten into you throughout your CS career to use ‘using’, there are times when the singleton model (and not invoking using) are more favourable to your software design needs, expectations, and requirements than what you’ve been taught is the best practice.

Happy coding! ūüôā

Announcing ‘Tomte’: The Customisable Remote Administration Tool for Windows Systems

TL;DR – I’ve released source code for remote systems administration via PowerShell + WCF + WindowsService, here, under the Mozilla Public License 2.0.¬†

Windows has a huge, glaring gap where Linux really shines: Remote configuration via tools. Sure, there’s DSC (Desired State Configuration) but it doesn’t help much for run-time automation and administration.

Tomte¬†(o, as in phone, and ‘e’, as in meh) is a framework (though lacking in some features) that was written to primarily address that and give SRE/DevOps teams a tool to quickly add an activity to be used (just add a PowerShell command and then the corresponding activity).

First things, first: We have to set the SQL Server up. Install your flavour of SQL server (I’ve port this code twice, now, so I just kept the instance name, as that made life easier) and run the following commands from the command line, replacing the instance name with your SQL Server instance and the database name with the database that you created.

osql -E -S .\SQL2008Express -d WorkflowInstanceStore -i C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SQL\en\SqlWorkflowInstanceStoreSchema.sql

osql -E -S .\SQL2008Express -d WorkflowInstanceStore -i C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SQL\en\SqlWorkflowInstanceStoreLogic.sql

IMPORTANT: If you want to configure the service to use a user-account, please change that in the source code and add permissions for the account to the SQL database; otherwise, the SQL database will require Anonymous Logon permissions, as the Local System account used for the Windows Service is obfuscated as an anonymous logon on SQL Server.

Now that the database is set-up, you’ll need to punch a hole in your firewall to listen on port 65534. You can change the listen port in the application configuration file of the Windows Service (Fels√∂kning.Tomte.AdminService) via the baseAddress setting.

        <host>

<baseAddresses>

<!– NOTE: The ‘*’ allows the service to install on any given machine –>

<add baseAddress=”http://*:65534/WorkflowService/service”/>

</baseAddresses>

</host>

Now that we have the SQL database ready and we’ve punched a hole in the firewall, we should install the Windows Service, first. Ensure that the build configuration of all of the projects is set to ‘x64’ and clean/build the solution.

To install the windows service, we’ll leverage the standard tools that ship with .NET, to prevent any cursory problems with “specialised” versions of these tools. In an elevated command (or PowerShell) window, run the following to install the service, replacing the path with your build’s output path.

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe

Installationsverktyg för Microsoft (R) .NET Framework, version 4.7.3190.0

Copyright (C) Microsoft Corporation. Med ensamrätt.

 

 

Kör en överförd installation.

 

Startar installationsfasen av installationen.

Se loggfilen om du vill ha information om installationsförloppet för sammansättningen C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe.

Filen finns på C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.InstallLog.

Installerar sammansättningen C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe.

Berörda parametrar är:

logtoconsole =

assemblypath = C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe

logfile = C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.InstallLog

Installerar tj√§nsten Fels√∂kning.Tomte.AdminService…

Tjänsten Felsökning.Tomte.AdminService har installerats.

Skapar EventLog-k√§llan Fels√∂kning.Tomte.AdminService i loggen Application…

 

Installationsfasen slutfördes och allokeringsfasen inleds.

Se loggfilen om du vill ha information om installationsförloppet för sammansättningen C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe.

Filen finns på C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.InstallLog.

Utför sammansättningen C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe.

Berörda parametrar är:

logtoconsole =

assemblypath = C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe

logfile = C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.InstallLog

 

Allokeringsfasen slutfördes.

 

Den överförda installationen slutfördes.

Now that the Windows Service is installed, we need to start it. You can do this via any number of means. Start>Run>services.msc is an easy way to do that.

With the service running, we can now import the PowerShell module.

Import-Module “C:\Code\git\felsokning\Tomte\Fels√∂kning.Tomte\Fels√∂kning.Tomte.PowerShell\bin\x64\Debug\Fels√∂kning.Tomte.PowerShell.dll” -Verbose

VERBOSE: Loading module from path ‘C:\Code\git\felsokning\Tomte\Fels√∂kning.Tomte\Fels√∂kning.Tomte.PowerShell\bin\x64\Debug\Fels√∂kning.Tomte.PowerShell.dll’.

VERBOSE: Importing cmdlet ‘Update-RemoteWindowsSystem’.

VERBOSE: Importing cmdlet ‘Test-RemotePortConnectivity’.

VERBOSE: Importing cmdlet ‘Test-RemoteFileExists’.

VERBOSE: Importing cmdlet ‘Start-RemoteSecureDelete’.

VERBOSE: Importing cmdlet ‘Set-RemoteComputerName’.

VERBOSE: Importing cmdlet ‘Set-RemoteSymbolServerEnvironmentVariable’.

VERBOSE: Importing cmdlet ‘Restart-RemoteService’.

VERBOSE: Importing cmdlet ‘Restart-RemoteSystem’.

VERBOSE: Importing cmdlet ‘Request-DevOpsElevation’.

VERBOSE: Importing cmdlet ‘Install-RemoteSysInternals’.

VERBOSE: Importing cmdlet ‘Get-RemoteDateTime’.

VERBOSE: Importing cmdlet ‘Get-RemoteFileText’.

VERBOSE: Importing cmdlet ‘Get-RemoteFreeDiskSpace’.

VERBOSE: Importing cmdlet ‘Get-RemoteLoggedOnUsers’.

VERBOSE: Importing cmdlet ‘Get-RemoteOSVersion’.

VERBOSE: Importing cmdlet ‘Get-RemotePingResponse’.

VERBOSE: Importing cmdlet ‘Get-RemoteProcessIds’.

VERBOSE: Importing cmdlet ‘Get-RemoteProcessThreads’.

VERBOSE: Importing cmdlet ‘Get-RemoteServerTimeSkew’.

VERBOSE: Importing cmdlet ‘Get-RemoteSystemUptime’.

VERBOSE: Importing cmdlet ‘Get-RemoteWebResponseString’.

VERBOSE: Importing cmdlet ‘Get-RemoteWindowsEvents’.

VERBOSE: Importing cmdlet ‘Edit-RemoteConfigurationFile’.

VERBOSE: Importing cmdlet ‘Copy-RemoteFiles’.

VERBOSE: Importing cmdlet ‘Copy-RemoteImagesAndLibrariesForProcess’.

Now that the module is loaded, you can run commands against the remote (or local) endpoint running the Windows Service. (As you can see, I’ve found a localisation bug that I need to sort-out with the return from the DateTimeActivity – 05-01-2019 can easily be May 1st or the 5th of January, depending on how you datetime.)

Get-RemoteDateTime -Server 192.168.0.252

den 5 januari 2019 15:00:02

 

Get-RemoteFreeDiskSpace -Server 192.168.0.252

Drive C:\ has 87.52% free

Drive D:\ has 90.22% free

 

Get-RemoteOSVersion -Server 192.168.0.252 -Kernel32

Major  Minor  Build  Revision

—–¬† —–¬† —–¬† ——–

10     0      17763  1

 

Test-RemotePortConnectivity -Server 192.168.0.252 -TargetHost 8.8.8.8 -Port 53

True

Now that we’ve run a few workflows, let’s check the SQL database and verify that the data we expect to find is there.

SQLQuery

SQL Query showing the executions of the Workflows on the machine.

…and that’s just about it.

Hope that this helps someone at some point in the some future. ūüôā

C++: Using the Luhn Algorithm to Validate the CheckSum in the Personnummer Supplied in User Input

The Swedish Personnummer uses a variant of the Luhn Algorithm to generate a checksum (technically, a check digit) value that is is appended to the end of the personnummer. So, forexample, the nine-digit number YYMMDD-SSS would become YYMMDD-SSSC with the tenth digit being the checksum.

The model for generating the checksum is created by multiplying the alternating digits by a 2 or a 1 and, then, adding the sum of the products. In the nine-digit series, this means 212121212. So, for example, the number 010214-010 would become (0x2) + (1×1) + (0x2) + (2×1) + (1×2) + (4×1) + (0x2) + (1×1) + (0x2). When the product is greater than nine, the sum of those numbers is added. So, for example, 2×7 = 14 –> 1 + 4 = 5 and, thus, our result would be five for that single instance of digit.

The last number in the sum is then subtracted from 10 to create the checksum number. So, for example, 46 –> 6 and 10-6 = 4, and 4 becomes our checksum value.

Below is an C++ program to validate the checksum for the provided personnumer, given in the user-input. PersonnummerSet is merely a struct of ints that I’ve created in a header file, so that it can be referenced by other libraries (either by direct assignment to type or pointer). StringMagic is another header file that uses std::string.erase/std::remove to remove the ‘-‘ character from the input (Swedish Personnummers are¬†always written as YYMMDD-SSSC.)

#include <cstring> // Replacing the old and busted with the new hotness.
#include <iomanip>
#include <iostream>
#include <cstdio> // Replacing the old and busted with the new hotness.
#include "Personnummerset.h"
#include "StringMagic.h"

class Personnummer
{
public:
    /**
     *  The PersonNumber is a property of type PersonnnummerSet, which is used to process the digits
     *  from the personnummer provided.
     */
    PersonnummerSet PersonNumber {};

    /**
     *  Initializes a new instance of the <see cref="Personnummer" /> class.
     * @param number - The converted long from the user's input.
     */
    explicit Personnummer(long number)
    {
        // We separate the three digit serial to future-proof for deriving sex of the individual in future checks.
        this->PersonNumber.Year = static_cast<int>(number / 100000000 % 100);   // First 2 integers     (0&1)
        this->PersonNumber.Month = static_cast<int>(number / 1000000 % 100);    // Second 2 integers    (2&3)
        this->PersonNumber.Day = static_cast<int>(number / 10000 % 100);        // Third 2 integers     (4&5)
        this->PersonNumber.SerialNumber = static_cast<int>(number / 100 % 100); // Fourth 2 integers    (6&7)
        this->PersonNumber.Sex = static_cast<int>(number / 10 % 10);            // First 1 integer      (8)
        this->PersonNumber.CheckSum = static_cast<int>(number % 10);            // Second 1 integer     (9)
    }

public:
    /**
     *  Generates the Luhn Algorithm checksum and compares that from the checksum given from the user's input.
     * @return A boolean indicating of the calculated checksum matches the provided checksum.
     */
    bool ValidateCheckSum()
    {
        return this->PersonNumber.CheckSum == this->GenerateChecksum();
    }

private:
    /**
     * This is a variation of the Luhn Algorithm, which is used to generate the checksum from the
     * first nine digits of the personnummer. Each value in the first nine digits is multiplied by
     * either a 2 or a 1. See: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2773709/figure/Fig1/
    */
    int GenerateChecksum()
    {
        int firstCheck;
        int fifthCheck;
        int seventhCheck;
        int ninthCheck;
        int firstYear = PersonNumber.Year > 9 ? PersonNumber.Year / 10 % 10 : 0;
        int secondYear = PersonNumber.Year%10;
        int firstMonth = PersonNumber.Month > 9 ? PersonNumber.Month / 10 % 10 : 0;
        int secondMonth = PersonNumber.Month%10;
        int firstDay = PersonNumber.Day > 9 ? PersonNumber.Day / 10 % 10 : 0;
        int secondDay = PersonNumber.Day%10;
        int firstSerial = PersonNumber.SerialNumber/10%10;
        int secondSerial = PersonNumber.SerialNumber%10;

        int firstYearDigit = firstYear * 2;
        if (firstYearDigit > 9)
        {
            int firstSum = firstYearDigit/10%10;
            int secondSum = firstYearDigit%10;
            firstCheck = firstSum + secondSum;
        }
        else
        {
            firstCheck = firstYearDigit;
        }

        int secondCheck = secondYear * 1;
        int thirdCheck = firstMonth * 2;
        int fourthCheck = secondMonth * 1;
        int firstDayCheck = firstDay * 2;
        if(firstDayCheck > 9)
        {
            int firstSum = firstDayCheck/10%10;
            int secondSum = firstDayCheck%10;
            fifthCheck = firstSum + secondSum;
        }
        else
        {
            fifthCheck = firstDayCheck;
        }

        int sixthCheck = secondDay * 1;
        int firstDigitRandom = firstSerial * 2;
        if (firstDigitRandom > 9)
        {
            int firstSum = firstDigitRandom/10%10;
            int secondSum = firstDigitRandom%10;
            seventhCheck = firstSum + secondSum;
        }
        else
        {
            seventhCheck = firstDigitRandom;
        }

        int eighthCheck = secondSerial * 1;
        int sexCheck = PersonNumber.Sex * 2;
        if(sexCheck > 9)
        {
            int firstSum = sexCheck/10%10;
            int secondSum = sexCheck%10;
            ninthCheck = firstSum + secondSum;
        }
        else
        {
            ninthCheck = sexCheck;
        }

        int sum = firstCheck + secondCheck + thirdCheck + fourthCheck + fifthCheck + sixthCheck + seventhCheck + eighthCheck + ninthCheck;
        int lastOfSum = sum%10;
        int checkSum = 10 - lastOfSum;
        return checkSum;

    }
};

int main()
{
    std::string user_input;
    std::cout << "Enter Personnummer (YYMMDD-SSSC): " << std::endl;
    std::cin >> user_input;

    // Necessary or the long conversion treats '-' or '+' as a delimiter.
    // NOTE: People aged over 99 will always have '+' in their personnummer.
    if(user_input.find('-') != std::string::npos)
    {
        StringMagic::RemoveDashFromString(user_input);
    }
    else if (user_input.find('+') != std::string::npos)
    {
        StringMagic::RemovePlusFromString(user_input);
    }

    // Smart-pointers are the future...
    std::unique_ptr<Personnummer> personNumber (new Personnummer(std::stol(user_input)));
    std::cout << std::boolalpha;
    std::cout << "CheckSum Passes: " << personNumber->ValidateCheckSum() << std::endl;

    personNumber.reset();
}

The above code can be used to validate almost any personnummer – save for those individuals whom are over 99 years of age, as the separator changes from ‘-‘ to ‘+’.

…and that’s about the extent of fun with Swedish Personnummers in C++ that this post will cover.

Thanks for coming to this NERDTalk‚ĄĘ and happy programming!

C++: Learning About Virtual Classes

Over the weekend, I was given something to learn for a potential job (in Sverige) and that was Virtual Classes in C++. If you’re familiar with Partial Classes the idea kind of related, only¬†it’s better. I’m sure how much of a pain it will be to debug but that’s the next thing that I want to test.

Anyways, Virtual Classes work off of inheritence and just like inheritence, you’re “wrapping” one object around another¬†but with virtual classes, the exposure is seemless.

Take these two classes for a principle example:

#include iostream
#include cstring // Replacing the old and busted with the new hotness.

class LabEquipment
{
    public:
        explicit LabEquipment(int number)
        {
            std::cout << "Lab Equipment: " << number << "\n";
        }

        virtual void LabWrite(std::string message)
        {
            std::cout << "Writing " << message << " from LabEquipment.\n";
        }
};

class Tubes : virtual public LabEquipment
{
    public:
        Tubes(int tubes, int number)
                : LabEquipment(number)
        {
            std::cout << "Tubes: " << tubes << "\n";
        }

        virtual void TubesWrite(std::string tubesMessage)
        {
            std::cout << "Writing " << tubesMessage.c_str() << " from Tubes.\n";
        }
};

I can then write the following to leverage both Tubes and LabEquipments classes:

// Object
Tubes tubes(2, 3);
tubes.TubesWrite("hello");
tubes.LabWrite("hello, again, ");

// Pointer
Tubes * pTubes = new Tubes(3,4);
pTubes->TubesWrite("hello");
pTubes->LabWrite("hello, again,");

If I debug this in CLion (on Ubuntu 18.04LTS), then I get what I would expect:

Lab Equipment: 3
Tubes: 2
Writing hello from Tubes.
Writing hello, again,  from LabEquipment.
Lab Equipment: 4
Tubes: 3
Writing hello from Tubes.
Writing hello, again, from LabEquipment.

Note that I didn’t¬†have to do anything else but declare the class’ inheritence for the methods to be exposed. None of that¬†this stuff is necessary for it for it to be exposed, as it’s purely abstracted from the child to the parent.

In this way, C++ affords more versatility that .NET, in that, if I¬†truly need to change any part of a class, there needn’t be any further changes – save on the caller.

Now, suppose that I declare the same method twice:

class ShowMessage
{
    public:
        explicit ShowMessage{};
    
        void virtual OutMessage(std::string message)
        {
            std::cout << "Writing " << message << " from WriteMessage.";
        }
};

class DisplayMessage : virtual public ShowMessage
{
    public:
        DisplayMessage()
                : ShowMessage()
        {};
        
        void OutMessage(std::string message)
        {
            std::cout << "Writing " << message << " from DisplayMessage";
        }
};

Our compiler, if it’s anything worwhile, should immediately alert us that we hiding the method; which, in this case, happens.

Markering_027

The IDE telling us that we’ve errored and suggesting ways to fix it.

If we override the method we can just drive on, as if nothing ever happened. We can also delete the method in DisplayMessage (which is what we should really do, as it’s redundant code already accomplished from within the ShowMessage class).

Now, let’s suppose we look at properties. Here’s a basic set of classes with int properties:

class FirstCount
{
    public:
        int Forsta;

    public:
        explicit FirstCount(int count)
        {
            Forsta = count;
        };
};

class SecondCount : virtual public FirstCount
{
    public:
        int Andra;

    public:
        SecondCount(int secondCount, int firstCount)
                : FirstCount(firstCount)
        {
            Andra = secondCount + Forsta;
        };
};

We can then construct an object that references them.

SecondCount secondCount(240, 547);
int first = secondCount.Forsta;
int second = secondCount.Andra;

When we debug, we can see that the value is what we’d expect (without having to have had used¬†this).

Markering_028

You can see that the vlaue for second/Andra is the sum of 240 and 547, the 547 having been passed through from the FirstCount class.

…And that’s about as far as I’ve gotten, really… There’s a whole diamond thing that we could get into but I can’t be arsed to get¬†that complicated with it, yet.

Anyways, thanks for coming to this NERDTalk‚ĄĘ and happy programming!

Wait-Chain Traversal: Or, How We Can Use PowerShell to JIT C# to Load an Unmanaged Assembly (C++), InterOping With Windows APIs, Returning that Data Back to PowerShell

So, as the long-winded title infers, today I’ll be covering something that I wrote a long time ago and have recently re-written (albeit, probably badly) for you to use and/or learn from.

In this case, we’re using a PowerShell script, which JITs C# code, the C# code calls into an unmanaged DLL (C++), and that calls into an Windows API. Once the data has been obtained from the Windows API, we pass the data back from the unmanaged assembly to the managed code (via Marshal) and then return that back to the PowerShell instance to be displayed to the user.

Before we dive into the what we’re doing, we should cover some key concepts. The first is JIT’ing. JIT stands for “Just-In-Time” (Compilation) and the name is slightly a misnomer but we’ll cover that in a second. So, in JIT, what happens is that the run time precompiles the code before it’s ran. This is important because a key-concept in exception handling is the runtime’s seek operation to find a handler for an exception that is thrown. You’ll often see this as a FirstChanceException in a dump file. In PowerShell, we have the added ability to leverage the JIT compilation by passing source code as a type into the App’s Domain. It’s important to distinguish that once the App Domain has been disposed of, the type specified is lost and has to be re-instantiated again.

So, what – exactly – is this code going to be doing? Well, since Windows Vista, the Windows Operating System exposes the Wait Chain Traversal API. You can see a demonstration of this API in Task Manager: Go to the Details tab, right click on a process and click “Analyze Wait Chain”.

Since Windows Server 2016 Core doesn’t include a desktop or any GUI interfaces, a more robust way was needed to obtain the same information in production, to determine if the reason an application wasn’t responding or performing work was because the threads were blocked.

When you run the code, you can tell if this is the case or not by something like the following:

12972   [7464:12972:blocked]->[ThreadWait]->[7464:12968:blocked]->[End]

Where the first thread is blocked by a thread wait on the the second thread, which is also (itself) blocked.

So, first things first, the PowerShell code. Take a peek here to see that. Note that the Source code is contained with a specific character-delimited string @”<code>”@. After that we add a Type, pointing it to the source code we’ve defined and referencing the assemblies that we’ll need for this type to work. Worthy of noting is that when we add this type, it is exposed in PowerShell the same way any normal .NET type is, via the []:: convention.

Note that in the C# source we import the unmanaged DLL and reference the exposed method. In the body of the code, we also construct an IntPtr to reference for the return. So, now, we get to Marshalling.

An IntPtr is, quite literally, a pointer or handle to an object. A pointer is a reference to memory where an object exists and the object is typically delimited by characters to signify the termination of it (e.g.: the end of a string is null-terminated). A handle is roughly the same premise but the handle abstracts memory management from the caller. So, at 200 ticks, the handle could point to address 0x000001 and at 369 ticks, it could point to 0x34778.

Alright, so why this matters is because when we pass from unmanaged code back to managed code, there’s nothing that implicitly tells the managed code where to find the object in native memory; so, we have to pass a pointer to the object back to managed (I believe managed creates it’s own copy and creates an address for that object) and, using that, we can then try to convert the passed object from a native string into a managed string (via Marshalling).

What about this unmanaged code I keep hearing about? Oh, well… You can find that here. Don’t forget to add the headers referenced in stdafx.h, or your compiler will cry bloody murder.

So, how this works is: The script is called via PowerShell. After some magic to verify that we weren’t given junk data, then PowerShell JIT’s the C# code and performs the runtime operations. The compiler loads the unmanaged DLL into memory. The C# code then calls into the unmanaged DLL via the exposed method (declspec/dllexport/cdecl). The unmanaged code performs it’s work and returns the string back to the caller – unaware that the caller is managed code. The managed code creates an IntPtr to reference the return and then Marshal is called to convert the native string into a managed string. This is then returned back to the user. In the case of multiple instances of a process, the managed string is added to an array and that array is returned.

While it may not seem like much and seem like overglorified complication just to check for threads on wait chaings, it was code that was written to be used in production where we had no desktop environments and we had to determine if this was the case.

I hope that someone gets some kind of use out of it. ūüôā

Until next time.

C#: Returning an Object via System.Threading.Tasks.Task

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

In programming something (in EWS), discovered the joys of what I believe was ‘lock contention’. To explain, first we need to cover Tasks.

Async Tasks (which call ‘await’ against other tasks) will only perform the action requested, if you do not specify a managed object to handle. For example, if I call an async for a string and do not specify that I am expecting an object in return, this is what the code will look like (and will introduce our problem):

string noDataReturns = await System.Threading.Tasks.Task.Run(() => this.GetMeTheStringAsync().Result);

private async Task GetMeTheStringAsync()

{

return await System.Threading.Tasks.Task.Run(() => this.GetMeTheString());

}

private string GetMeTheString()

{

return “This is not the string you’re looking for.”;

}

If, instead, I tell the task what object I expect to get in return, when the task completes, the result will be object that is passed back – instead of the result of the task:

string dataReturns = await System.Threading.Tasks.Task<string>.Run(() => this.GetMeTheStringAsync().Result);

private async Task<string> GetMeTheStringAsync()

{

return await System.Threading.Tasks.Task<string>.Run(() => GetMeTheString());

}

private string GetMeTheString()

{

return “This is the string you’re looking for.”;

}

This is probably common-place parlance in the .NET developer’s world but I had discovered this when I was spawning a Task that would return a DataTable object but did not specify that I expecting an object in return. As such, the windows form was rendered useless/locked, as I placed the DataTable’s data source as the result of the Task but there was no data to put in the data table.

 

C#: Returning ADSI COM Properties of a User Object (Or Any Object, Really)

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

A few months ago, I was working on a project to query for specific AD properties of a user-object programmatically. I knew the properties I wanted to return and I had worked with returning properties in ExBPA/HRC. I hadn’t, however, found the joys of receiving a System.__COM object in any of my returns until now.

To explain this, you should familiarize yourself with ADSI (Active Directory Service Interfaces), if you’ve never been exposed to it, before. As the previous link points out, ADSI is a COM (Component Object Model), and – as such – we will get a return of ‘System.__COM’, if we fail to pull the data in the expected format.

So, how was I to return the data from the COM? Well, as it turns out, there’s ‘deprecated’ documentation which helped me farther than any blog, technical bulletin, or reference did. You can find it, here. (Apologies, apparently all of the English versions have been pulled because it was deprecated.)

Using some ingenuity and a little luck, I found the answer to my problem: return the value I’m querying for as ‘ActiveDs.IADsLargeInteger’.

So, armed with this knowledge, I could now pull the properties I wanted to return in usable context, like the following:

ActiveDs.IADsLargeInteger recipientTypeDetails = (ActiveDs.IADsLargeInteger)userResult.Properties[“msExchRecipientTypeDetails”].Value as ActiveDs.IADsLargeInteger;

Once I had the data ‘out’, as it were, I could try to manipulate it:

long recipTypeDetails = recipientTypeDetails.LowPart;

 

I realize this doesn’t mean much to some people (maybe a lot) but I figured if I could save one person the hours it took me to find the answer, then it was well worth the time in writing this.

Happy coding!