A Paranoid’s Guide to Securing Windows 10

So, you’re already taping over your webcam and microphone? Then this may be the guide for you!

Disclaimer: This guide is for educational purposes only, the author is not a security expert and this guide was written to share his experiences. Tampering with the Windows Firewall settings is not to be taken lightly and can lead to loss of functionality & connectivity. Do not perform any  of the steps in this guide yourself unless you have the necessary technical know-how to fix any problems that might arise from following it. The author take no responsibility for any problem, loss of functionality, or damages that may arise by following this guide. 

In this blog I go through how I secured my Windows 10 using firewall rules so that only the most necessary programs, services, and apps have access to the internet while blocking out all the unecessary stuff.

I opened the Windows Firewall from the  Start Meny by typing “Firewall”. Then I selected “Advanced Settings” on the left side.

firewall

Now I took a backup of my old firewall settings by opening the Actions menu and selecting Export Policy, and saving the old firewall policies to a backup device of mine. If something went wrong then I could always import the old policy. It’s always good to make a backup.

After backing up my old firewall policies, I clicked Windows Firewall Settings and blocked both inbound and outbound connections that do not match a rule.

firewall

Then I selected Outbound Rules and disabled and blocked everything on the list except:

  • Core Networking – DNS (UDP-Out)
  • Core Networking – Dynamic Host Configuration Protocol (DHCP-Out)

Now everything unneccesary is blocked.

Now we need to allow Windows basic functionality access to the internet, so it can update itself a.s.f. Please mind that the locations of the executables below may differ, espessially if you have a non-english Windows, so make sure that you find the correct path on your Windows 10.

Then I add new Outbound Rules for the following:

  • Name: Allow Windows COM Surrogate
  • Program path: %SystemRoot%\WinStore\WSHost.exe
  • Name: Allow Windows Defender Command Line
  • Program path: %ProgramFiles%\Windows Defender\MpCmdRun.exe
  • Name: Allow Windows Defender MpUXSrv.exe
  • Program path: %ProgramFiles%\Windows Defender\MpUXSrv.exe
  • Name: Allow Windows Defender MsMpEng.exe
  • Program path: %ProgramFiles%\Windows Defender\MsMpEng.exe
  • Name: Allow Windows Defender Network Inspection Service
  • Service: Windows Defender Network Inspection Service
  • Name: Allow Windows Defender NisSrv.exe
  • Program path: %ProgramFiles%\Windows Defender\NisSrv.exe
  • Name: Allow Windows Defender Service
  • Service: Windows Defender Service
  • Name: Allow Windows Defender UI
  • Program path: %ProgramFiles%\Windows Defender\MSASCui.exe
  • Name: Allow Windows Help
  • Program path: \Windows\HelpPane.exe
  • Name: Allow Windows Services
  • Program path: %SystemRoot%\System32\svchost.exe
  • Name: Allow Windows Store App
  • App: Microsoft.WindowsStore_…
  • Name: Allow Windows Store Service
  • Service: Windows Store Service
  • Name: Allow Windows Time
  • Service: Windows Time
  • Name: Allow Windows Trusted Installer
  • Program path: c:\Windows\servicing\trustedinstaller.exe
  • Name: Allow Windows Update
  • Program path: %SystemRoot%\System32\wuauclt.exe
  • Name: Allow Windows Update Service
  • Service: Windows Update Service
  • Name: Allow WmiPrvSE.exe
  • Program path: %SystemRoot%\System32\wbem\WmiPrvSE.exe
  • Name: Allow WmiPrvSE.exe (64-bit)
  • Program path: %SystemRoot%\SysWOW64\wbem\WmiPrvSE.exe
  • Name: Allow Edge
  • App: Microsoft.MicrosoftEdge_…

You might want to explictly allow every service rather than use Allow Windows Services above, but I’ve choosen to trust all services here.

That is what I discovered I needed to give access to as a very minimum, afterwards I added access to Google Chrome and other software I use day to day.

 

 

Qucikstart Templates using Azure Powershell

Here is a tiny tutorial of how to deploy a Azure Quickstart Template using Azure Powershell.

Quickstart Templates list

 

Working with Azure Resource Manager

  • Prerequisites:
    • Install PackageManagement PowerShell Modules: https://www.microsoft.com/en-us/download/details.aspx?id=51451
    • Start Powershell as an administrator.
    • Install Azure RM modules:
      • Install-Module AzureRM
      • , or Install-AzureRM (Deprecated)
    • Update help-files:
      • Update-Help
    • https://azure.microsoft.com/en-us/documentation/articles/powershell-azure-resource-manager/
    • Log in: Add-AzureRmAccount
    • List Azure Resource Manager kommandoer:
      • Get-Command -Module AzureRM.Resources | Get-Help | Format-Table Name, Synopsis
    • Create new Azure RM Resource Group:
      • New-AzureRmResourceGroup -Name TestRG1 -Location “West US”
    • Deploy using Cisco CRS 1000V template:
      • New-AzureRmResourceGroupDeployment -ResourceGroupName TestRG1 -administratorLogin exampleadmin -TemplateUri https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/cisco-csr-1000v/azuredeploy.json
      • , alternatively you can download the main template and the parameter JSON file, modify both these JSON locally accoring to your needs, and deploy directly from your local workstation or server. Please note that all the other Quickstart template files must still be available online as Azure  will try to access these directly via the web. Here is a Powershell commando example of deploying using a modified Azure Quickstart template and argument JSON-files:New-AzureRmResourceGroupDeployment -ResourceGroupName TestRG1 -TemplateFile c:\temp\azuredeploy.json -TemplateParameterFile c:\temp\azuredeploy.parameters.json

 

How to work with file paths longer than 260 characters in .NET

In Windows the full path to a file can not be longer than 260 characters, if you wan’t to use longer paths you must call the Win API directly using UNC paths and your file paths can be 32,767 characters long, I found a .NET class some years ago that does this, I did not write this code originally but sadly I did not find the original article when looking for it today so I will just enter my modified code here for demonstration purposes, the code is slightly altered from the original code and has some extra functionalty.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.IO;

namespace MyStuff.Services.IO.File
{
    /// <summary>
    /// Class for communicating with the Windows kernel library for low-level disk access.
    /// The main purpose of this class is to allow for longer file paths than System.IO.File,
    /// this class handles file paths up to 32,767 characters. 
    /// Note: Always be careful when accessing this class from a managed multi-threaded application
    /// as the unmanaged Windows kernel is different, this "crash" causes application unstability 
    /// if not handled properly.
    /// TODO: Look into if there are any significant gains on 64-bit systems using another kind of 
    /// core component than kernel32.dll.
    /// </summary>
    public class Win32File
    {
        #region DLLImport's
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern bool MoveFile(string lpExistingFileName, string lpNewFileName);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern bool DeleteFile(string lpFileName);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern bool CreateDirectoryW(string lpPathName, IntPtr lpSecurityAttributes);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern SafeFileHandle CreateFileW(string lpFileName, uint dwDesiredAccess,
                                              uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
                                              uint dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern uint SetFilePointer(SafeFileHandle hFile, long lDistanceToMove, IntPtr lpDistanceToMoveHigh, uint dwMoveMethod);

        #endregion

        // uint GetMode( FileMode mode )
        // Converts the filemode constant to win32 constant
        #region GetMode
        private uint GetMode(FileMode mode)
        {
            uint umode = 0;
            switch (mode)
            {
                case FileMode.CreateNew:
                    umode = Win32FileAttributes.CREATE_NEW;
                    break;
                case FileMode.Create:
                    umode = Win32FileAttributes.CREATE_ALWAYS;
                    break;
                case FileMode.Append:
                    umode = Win32FileAttributes.OPEN_ALWAYS;
                    break;
                case FileMode.Open:
                    umode = Win32FileAttributes.OPEN_EXISTING;
                    break;
                case FileMode.OpenOrCreate:
                    umode = Win32FileAttributes.OPEN_ALWAYS;
                    break;
                case FileMode.Truncate:
                    umode = Win32FileAttributes.TRUNCATE_EXISTING;
                    break;
            }
            return umode;
        }
        #endregion

        // uint GetAccess(FileAccess access)
        // Converts the FileAccess constant to win32 constant
        #region GetAccess
        private uint GetAccess(FileAccess access)
        {
            uint uaccess = 0;
            switch (access)
            {
                case FileAccess.Read:
                    uaccess = Win32FileAttributes.GENERIC_READ;
                    break;
                case FileAccess.ReadWrite:
                    uaccess = Win32FileAttributes.GENERIC_READ | Win32FileAttributes.GENERIC_WRITE;
                    break;
                case FileAccess.Write:
                    uaccess = Win32FileAttributes.GENERIC_WRITE;
                    break;
            }
            return uaccess;
        }
        #endregion

        // uint GetShare(FileShare share)
        // Converts the FileShare constant to win32 constant
        #region GetShare
        private uint GetShare(FileShare share)
        {
            uint ushare = 0;
            switch (share)
            {
                case FileShare.Read:
                    ushare = Win32FileAttributes.FILE_SHARE_READ;
                    break;
                case FileShare.ReadWrite:
                    ushare = Win32FileAttributes.FILE_SHARE_READ | Win32FileAttributes.FILE_SHARE_WRITE;
                    break;
                case FileShare.Write:
                    ushare = Win32FileAttributes.FILE_SHARE_WRITE;
                    break;
                case FileShare.Delete:
                    ushare = Win32FileAttributes.FILE_SHARE_DELETE;
                    break;
                case FileShare.None:
                    ushare = 0;
                    break;

            }
            return ushare;
        }
        #endregion

        public bool Move(string existingFile, string newFile)
        {
            return Win32File.MoveFile(existingFile, newFile);
        }

        public bool CreateDirectory(string filepath)
        {
            // If file path is disk file path then prepend it with \\?\
            // if file path is UNC prepend it with \\?\UNC\ and remove \\ prefix in unc path.
            if (filepath.StartsWith(@"\\"))
                filepath = @"\\?\UNC\" + filepath.Substring(2, filepath.Length - 2);
            else
                filepath = @"\\?\" + filepath;
            return CreateDirectoryW(filepath, IntPtr.Zero);
        }

        public FileStream Open(string filepath, FileMode mode, uint uaccess)
        {
            //opened in the specified mode and path, with read/write access and not shared
            FileStream fs = null;
            uint umode = GetMode(mode);
            uint ushare = 0;    // Not shared
            if (mode == FileMode.Append) uaccess = Win32FileAttributes.FILE_APPEND_DATA;

            // If file path is disk file path then prepend it with \\?\
            // if file path is UNC prepend it with \\?\UNC\ and remove \\ prefix in unc path.
            if (filepath.StartsWith(@"\\"))
                filepath = @"\\?\UNC\" + filepath.Substring(2, filepath.Length - 2);
            else filepath = @"\\?\" + filepath;

            SafeFileHandle sh = CreateFileW(filepath, uaccess, ushare, IntPtr.Zero, umode, Win32FileAttributes.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            int iError = Marshal.GetLastWin32Error();
            if ((iError > 0 && !(mode == FileMode.Append && iError == Win32FileAttributes.ERROR_ALREADY_EXISTS)) || sh.IsInvalid)
            {
                throw new Exception("Error opening file; Win32 Error:" + iError);
            }
            else
            {
                fs = new FileStream(sh, FileAccess.ReadWrite);
            }

            // if opened in append mode
            if (mode == FileMode.Append)
            {
                if (!sh.IsInvalid)
                {
                    SetFilePointer(sh, 0, IntPtr.Zero, Win32FileAttributes.FILE_END);
                }
            }

            return fs;
        }

        public FileStream Open(string filepath, FileMode mode, FileAccess access)
        {
            //opened in the specified mode and access and not shared
            FileStream fs = null;
            uint umode = GetMode(mode);
            uint uaccess = GetAccess(access);
            uint ushare = 0;    // Exclusive lock of the file

            if (mode == FileMode.Append) uaccess = Win32FileAttributes.FILE_APPEND_DATA;

            // If file path is disk file path then prepend it with \\?\
            // if file path is UNC prepend it with \\?\UNC\ and remove \\ prefix in unc path.
            if (filepath.StartsWith(@"\\"))
                filepath = @"\\?\UNC\" + filepath.Substring(2, filepath.Length - 2);
            else
                filepath = @"\\?\" + filepath;

            SafeFileHandle sh = CreateFileW(filepath, uaccess, ushare, IntPtr.Zero, umode, Win32FileAttributes.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            int iError = Marshal.GetLastWin32Error();
            if ((iError > 0 && !(mode == FileMode.Append && iError != Win32FileAttributes.ERROR_ALREADY_EXISTS)) || sh.IsInvalid)
            {
                throw new Exception("Error opening file; Win32 Error:" + iError);
            }
            else
            {
                fs = new FileStream(sh, access);
            }

            // if opened in append mode
            if (mode == FileMode.Append)
            {
                if (!sh.IsInvalid)
                {
                    SetFilePointer(sh, 0, IntPtr.Zero, Win32FileAttributes.FILE_END);
                }
            }

            return fs;
        }

        public FileStream Open(string filepath, FileMode mode, FileAccess access, FileShare share)
        {
            //opened in the specified mode , access and  share
            FileStream fs = null;
            uint umode = GetMode(mode);
            uint uaccess = GetAccess(access);
            uint ushare = GetShare(share);
            if (mode == FileMode.Append) uaccess = Win32FileAttributes.FILE_APPEND_DATA;

            // If file path is disk file path then prepend it with \\?\
            // if file path is UNC prepend it with \\?\UNC\ and remove \\ prefix in unc path.
            if (filepath.StartsWith(@"\\"))
                filepath = @"\\?\UNC\" + filepath.Substring(2, filepath.Length - 2);
            else
                filepath = @"\\?\" + filepath;
            SafeFileHandle sh = CreateFileW(filepath, uaccess, ushare, IntPtr.Zero, umode, Win32FileAttributes.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            int iError = Marshal.GetLastWin32Error();
            if ((iError > 0 && !(mode == FileMode.Append && iError != Win32FileAttributes.ERROR_ALREADY_EXISTS)) || sh.IsInvalid)
            {
                throw new Exception("Error opening file Win32 Error:" + iError);
            }
            else
            {
                fs = new FileStream(sh, access);
            }
            // if opened in append mode
            if (mode == FileMode.Append)
            {
                if (!sh.IsInvalid)
                {
                    SetFilePointer(sh, 0, IntPtr.Zero, Win32FileAttributes.FILE_END);
                }
            }
            return fs;
        }

        public FileStream OpenRead(string filepath)
        {
            // Open readonly file mode open(String, FileMode.Open, FileAccess.Read, FileShare.Read)
            return Open(filepath, FileMode.Open, FileAccess.Read, FileShare.Read);
        }

        public FileStream OpenWrite(string filepath)
        {
            return Open(filepath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
        }

        public bool Delete(string filepath)
        {
            // If file path is disk file path then prepend it with \\?\
            // if file path is UNC prepend it with \\?\UNC\ and remove \\ prefix in unc path.
            if (filepath.StartsWith(@"\\"))
                filepath = @"\\?\UNC\" + filepath.Substring(2, filepath.Length - 2);
            else
                filepath = @"\\?\" + filepath;
            return DeleteFile(filepath);
        }
    }
}

Finding any innermost expression in any LINQ expression tree

Ever wanted to find an operator inside a LINQ expression tree? Here is a generic class that I wrote a while back to do just that.

using System.Linq.Expressions;

namespace ExpressionTreeHelper
{
    internal class InnermostMethodFinder : ExpressionVisitor
    {
        MethodCallExpression _innermostMethodExpression;

        readonly string _methodName ;

        public InnermostMethodFinder(string methodName)
        {
            _methodName = methodName;
        }

        public MethodCallExpression GetInnermostMehod(
            Expression expression)
        {
            Visit(expression);
            return _innermostMethodExpression;
        }

        protected override Expression VisitMethodCall(
            MethodCallExpression expression)
        {
            if (expression.Method.Name == _methodName) 
                _innermostMethodExpression = expression;

            Visit(expression.Arguments[0]);

            return expression;
        }
    }
}

Use it as follows to get find any LINQ-projections & conditionals:

using System.Linq;
using System.Linq.Expressions;

namespace LinqStuff
{
    internal class QueryContext<T>
    {
        static MethodCallExpression GetDataSourceQueryExpression(
            Expression expression)
        {
            // If expression represents an unqueried IQueryable data source instance, 
            // expression is of type ConstantExpression, not MethodCallExpression. 
            return (expression.Expression as MethodCallExpression);
        }

        internal static object Execute(Expression expression, 
            bool isEnumerable)
        {
            // The expression must represent a query over the data source. 
            var dsQueryExpression = GetDataSourceQueryExpression(expression);
            if (dsQueryExpression == null)
                throw new InvalidProgramException("No query over the data source was specified.");

            // Get projections
            var selectFinder = new InnermostMethodFinder("select");
            var selectExpression = selectFinder.GetInnermostMehod(dsQueryExpression);

            // Find the call to Where() and get the lambda expression predicate.
            var whereFinder = new InnermostMethodFinder("where");
            var whereExpression = whereFinder.GetInnermostMehod(dsQueryExpression);
            ...
        }
    }
}

Better protected license keys using Partial Key Verification

If you are developing commercial software and want to protect it using license keys, then you should have a look at Partial Key Verification. The strength of PKV over other license key generator software design patterns is that it you don’t have to expose your entire keygen in your license client code; making it harder for anyone to crack it.

For those of you developing in C# there is a GitHub project https://github.com/cuda/Partial-Key-Verification , which you can also download as a NuGet-package:

PM> Install-Package Partial.Key.Verification

Here is how you generate the license key on the server side using the customer e-mail:

using PartialKeyVerification;
using PartialKeyVerification.Checksum;
using PartialKeyVerification.Hash;

internal class LicenseServer
{
    static string MakeLicenseKey(string customerEmail)
    {
        var generator = new PartialKeyGenerator(new Adler16(), 
            new Jenkins96(), new uint[] { 1, 2, 3, 4 }) 
                { Spacing = 6 };
        return generator.Generate(customerEmail);
    }
}

, which would generate the license key QDKZUO-JLLWPY-XWOULC-ONCQIN-5R5X35-ZS3KEQ using a six-part keygen.

Here is how you validate the key using just one part of the keygen, use several parts if you think you need to, but remember that the point here is to not expose the entire keygen to crackers:

using PartialKeyVerification;
using PartialKeyVerification.Checksum;
using PartialKeyVerification.Hash;

internal class LicenseClient
{
    static bool IsValidKey(string key)
    {
        try
        {
            return PartialKeyValidator.ValidateKey(
                new Adler16(), new Jenkins96(), key, 0, 1);            
        }
        catch (Exception)
        {
            return false;
        }
    }
}

Bash demo in browser

A couple of years ago I made a live Bash demo using JavaScript and Q. Those not familiary with Q should get aquainted as the that Javscript library has some awesome functionality for asynchronous promises.

Click here for a fully functional open source demo..

HTML


<script src="//cdnjs.cloudflare.com/ajax/libs/q.js/1.0.0/q.js"></script>
<div id="wnd"></div>
<div id="log"></div>

<textarea rows="11" cols="50">
% cat example.c
#include <stdio.h>
int main()
{
  printf("Goodbye Cruel World!\n");
  return 0;
}
% make example.c -o example
% ./example
Goodbye Cruel World!
</textarea>

CSS


body {
  background: black;
}
#wnd {
  background: #232;
  border-radius: .2em;
  white-space: pre-wrap;
  padding: .5em;
  font-family: "Consolas", "Ubuntu Mono", "Monaco", monospace;
  color: white;
}
.prompt {
  color: #99aaee;
}
.cmd {
  color: #9e9e9C;
}

JQuery


var prompt;

function setPrompt(usr, domain)
{
  prompt = usr + '@' + domain + ' %';
}

function addOutput(s) {
  $('<div>').text(s).appendTo(wnd);
  return Q.delay(100);
//  return addPrompt();
}

function addInput(s) {
  var l = $('.prompt:last');
var e = $('<span>').addClass('cmd').appendTo(l);
    
  return addLettersRecursive(e, s);
}

function addPrompt() {
  var l = $('<div>').text(prompt).addClass('prompt').appendTo(wnd);
  return Q.delay(900);
}

function addLettersRecursive(container, s) {
  container.append(s.charAt(0)); // dangerous😦
  var row_complete = Q.defer();
  Q.delay(100).then(function() {
    if (s.length <= 1) {
      row_complete.resolve();
    }
    addLettersRecursive(container, s.substr(1)).then(function() {
      row_complete.resolve();
    })
  });
  return row_complete.promise;
}

$( document ).ready(function() {
  $('textarea').hide();
  
  setPrompt('inge', 'sparkledb.net');
  
  var lines = $('textarea').val().split('\n');
  
  var promise = new Q();
  
  promise = promise.then(function() 
  {  
    lines.forEach( function(item) {
      if (item[0] == '%')
      {
        promise = promise.then(function() 
        { return addPrompt(); })
        promise = promise.then(function() 
        { return addInput(item.substr(1)); })
      }
      else
      {
        promise = promise.then(function() 
        { return addOutput(item); })
      }
    })
  })
  promise.done();
  
});


Schemaless Azure Table Storage development

Azure Table Storage is a schema-less NoSQL database in the cloud. However, .NET developers still seem to to type all table storage entities – which is quite unnecessary. In this article, I will demonstrate how an un-typed entity approach could be solved. Version 2.5 of the Azure SDK or later is required.

First, let me demonstrate the final usage of such a schema-less approach for working with the Azure Table Storage.

// Create a dynamic object representation of the azure table storage service provider
dynamic storage = new DynStorage();

// Dynamically create a new user in the "Users" table with primary key "ihenriksen"
dynamic entity2 = storage.Users.ihenriksen;

// Add user name as a string
entity2.Name = "Inge Henriksen";

// Add user registration date
entity2.registered = DateTime.UtcNow;

// Save entity data to storage
entity2.Save();

// Later, we can access the new entity and its properties
dynamic entity3 = storage.Users.ihenriksen;
txtVal1.InnerText = entity3.Name;
txtVal2.InnerText = entity3.registered.ToString();

Notice that we never explicitly created the table “Users” or the untyped entity, rather it was created implicitly when we referenced it in our code – this is a very convenient way of working with tables & entities as it saves the developer a lot of time, whilst requiring less work for later changes due to its schema-less nature.

Let us look at the DynStorage class implementation. It inherits System.Dynamic.DynamicObject so that one can create tables in the storage “on the fly” like this:

dynamic storage = new DynStorage();
dynamic table = storage.newTable;

, this kind of code design pattern saves a developer time as he/she can create any table implicitly when in use for the first time.

using System.Dynamic;
using Microsoft.WindowsAzure.Storage;

namespace Www.Dyn
{
    public class DynStorage : DynamicObject
    {
        const string ConnectionString = "UseDevelopmentStorage=true;";

        // For Fiddler debugging:
        //const string ConnectionString = "UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://ipv4.fiddler";

        public CloudStorageAccount StorageAccount { get; protected set; }

        public DynStorage()
        {
            StorageAccount = CloudStorageAccount.Parse(ConnectionString);
        }
#region DynamicObject implementation
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = new DynTable(StorageAccount, binder.Name);
            return true;
        }
#endiregion
        public bool Delete(string tableName)
        {
            var tableClient = StorageAccount.CreateCloudTableClient();
            return tableClient.GetTableReference(tableName).DeleteIfExists();
        }
    }
}

Above, DynamicObject’sinterface implementation TryGetMember() works on a DynTable class which is a dynamic representation of a table in the Azure Table Storage. DynTable also allows you to delete a table given its name.

Now, let is look at DynTable. It allows us to work with untyped entities and therefore inherits System.Dynamic.DynamicObject, just like the the DynStorage class did. This allows you to create and work with untyped entities as follows:

dynamic storage = new DynStorage();
dynamic entity = storage.newTable3.user001212.birthyear= 1972;

Above, the table “newTable3”, the entity with primary key “user001212”, and the entity property birthyear integer are all created in one line – all pretty convenient and quick. Notice that there is no type casting.

using System;
using System.Dynamic;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;

namespace Www.Dyn
{
    public class DynTable : DynamicObject
    {
        public CloudStorageAccount StorageAccount { get; protected set; }
        public CloudTableClient TableClient { get; protected set; }

        public CloudTable Table { get; protected set; }

        CloudTable GetTable(string tableName, bool createIfNotExists = true)
        {
            var cloudTable = TableClient.GetTableReference(tableName);
            if (createIfNotExists)
                cloudTable.CreateIfNotExists();
            return cloudTable;
        }

        public DynTable(CloudStorageAccount storageAccount, string tableName)
        {
            StorageAccount = storageAccount;

            // Create the table client
            TableClient = StorageAccount.CreateCloudTableClient();

            // Get a table reference
            Table = GetTable(tableName);
        }

        public DynTableEntity Entity(string partitionKey, string rowKey = null)
        {
            return new DynTableEntity(this, partitionKey, rowKey);
        }

#region DynamicObject implementation
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var keys = binder.Name.Split('_');
            result = keys.Length == 1 ? new DynTableEntity(this, binder.Name) 
                : new DynTableEntity(this, keys[0], keys[1]);
            return true;
        }
#endregion

        /// <summary>
        /// Deletes table entities
        /// </summary>
        /// <param name="partitionKey">Partition key</param>
        /// <param name="rowKey">Row key</param>
        /// <returns>Number of deleted table entities</returns>
        public int Delete(string partitionKey, string rowKey = null)
        {
            // Keep track of number of deleted rows
            var numDeleted = 0;

            var query = new TableQuery().Where(rowKey == null
                ? String.Format("PartitionKey eq '{0}'", partitionKey)
                : String.Format("PartitionKey eq '{0}' and RowKey eq '{1}'", partitionKey, rowKey));


            foreach (var tableEntity in Table.ExecuteQuery(query))
            {
                Table.Execute(TableOperation.Delete(tableEntity));
                numDeleted++;
            }

            return numDeleted;
        }

    }
}

DynTable’s DynamicObject’sinterface implementation TryGetMember() works on a DynTableEntity class, which is a dynamic representation of a Azure Table Storage entity. Just like DynStorage and DynTable, DynTableEntity allows you to work with data in an untyped manner, thus you can add entity properties without the need for a predefined schema.

Lastly, let us look at the DynTableEntity class code.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;

namespace Www.Dyn
{
    public class DynTableEntity : DynamicObject, ITableEntity, IDictionary<string, EntityProperty>
    {
        IDictionary<string, EntityProperty> _properties;

        public DynTable DynamicTable { get; protected set; }

        public DynTableEntity(DynTable dynDynamicTable, string partitionKey = null, string rowKey = "")
        {
            PartitionKey = partitionKey;
            RowKey = rowKey;

            DynamicTable = dynDynamicTable;

            _properties = new Dictionary<string, EntityProperty>();
        }

        public static object GetEntityPropertyValue(EntityProperty value)
        {
            switch (value.PropertyType)
            {
                case EdmType.String:
                    return value.StringValue;
                case EdmType.DateTime:
                    return value.DateTime;
                case EdmType.Boolean:
                    return value.BooleanValue;
                case EdmType.Double:
                    return value.DoubleValue;
                case EdmType.Guid:
                    return value.GuidValue;
                case EdmType.Int32:
                    return value.Int32Value;
                case EdmType.Int64:
                    return value.Int64Value;
                case EdmType.Binary:
                    return value.BinaryValue;
                default:
                    return null;
            }
        }

        static EntityProperty GetEntityProperty(object value)
        {
            if (value == null) return new EntityProperty((string)null); // Force null to string cast
            if (value is string) return new EntityProperty((string)value);
            if (value is int) return new EntityProperty((int)value);
            if (value is long) return new EntityProperty((long)value);
            if (value is bool) return new EntityProperty((bool)value);
            if (value is DateTime) return new EntityProperty((DateTime)value);
            if (value is double) return new EntityProperty((double)value);
            if (value is Guid) return new EntityProperty((Guid)value);

            // If unsupported type, so try to convert it to a string
            return value.GetType() == typeof(byte[])
                ? new EntityProperty((byte[])value)
                : new EntityProperty(Convert.ToString(value));
        }

#region DynamicObject implementation
        public bool TryGetValue(string key, out EntityProperty value)
        {
            return _properties.TryGetValue(key, out value);
        }
#endregion

#region ITableEntity interface implementation

        public string PartitionKey { get; set; }

        public string RowKey { get; set; }

        public DateTimeOffset Timestamp { get; set; }

        public string ETag { get; set; }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = GetEntityPropertyValue(this[binder.Name]);
            return true;
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            this[binder.Name] = GetEntityProperty(value);
            return true;
        }

        public void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext)
        {
            _properties = properties;
        }

        public IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
        {
            return _properties;
        }
#endregion

#region IDictionary interface implementation
        public IEnumerator<KeyValuePair<string, EntityProperty>> GetEnumerator()
        {
            return _properties.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public void Add(KeyValuePair<string, EntityProperty> item)
        {
            _properties.Add(item);
        }

        public void Clear()
        {
            _properties.Clear();
        }

        public bool Contains(KeyValuePair<string, EntityProperty> item)
        {
            return _properties.Contains(item);
        }

        public void CopyTo(KeyValuePair<string, EntityProperty>[] array, int arrayIndex)
        {
            _properties.CopyTo(array, arrayIndex);
        }

        public bool Remove(KeyValuePair<string, EntityProperty> item)
        {
            return _properties.Remove(item);
        }

        public int Count
        {
            get { return _properties.Count; }
        }

        public bool IsReadOnly
        {
            get { return _properties.IsReadOnly; }
        }

        public bool ContainsKey(string key)
        {
            return _properties.ContainsKey(key);
        }

        public void Add(string key, EntityProperty value)
        {
            _properties.Add(key, value);
        }

        public bool Remove(string key)
        {
            return _properties.Remove(key);
        }

        public EntityProperty this[string key]
        {
            get
            {
                EntityProperty entityProperty;

                if (this.TryGetValue(key, out entityProperty)) return _properties[key];
                
                // Property not found in dictionary, so load it from the storage
                TableQuery query;

                if (String.IsNullOrEmpty(RowKey))
                {
                    // Get entity using partition key only
                    query = new TableQuery().Where(
                        String.Format("PartitionKey eq '{0}'", PartitionKey)
                        ).Select(new[] { key });
                }
                else
                {
                    // Get entity using both partition key and row key
                    query = new TableQuery().Where(
                        String.Format("PartitionKey eq '{0}' and RowKey eq '{1}'", PartitionKey, RowKey)
                        ).Select(new[] { key });
                }

                foreach (var tableEntity in DynamicTable.Table.ExecuteQuery(query))
                {
                    // Users should always assume property is not there in case another client removed it
                    if (!tableEntity.Properties.TryGetValue(key, out entityProperty))
                        throw new ArgumentNullException("key");

                    _properties[key] = entityProperty;
                }

                return _properties[key];
            }
            set
            {
                _properties[key] = value;
            }
        }

        public ICollection<string> Keys
        {
            get { return _properties.Keys; }
        }

        public ICollection<EntityProperty> Values
        {
            get { return _properties.Values; }
        }
#endregion

        /// <summary>
        /// Loads all the entity properties from the storage
        /// </summary>
        public IList<EntityProperty> GetAll()
        {
            var all = new List<EntityProperty>();

            // Query the storage
            var query = new TableQuery().Where(String.IsNullOrEmpty(RowKey) 
                ? String.Format("PartitionKey eq '{0}'", PartitionKey) 
                : String.Format("PartitionKey eq '{0}' and RowKey eq '{1}'", PartitionKey, RowKey));

            foreach (var prop in DynamicTable.Table.ExecuteQuery(query).SelectMany(
                tableEntity => tableEntity.Properties))
            {
                all.Add(prop.Value);
                _properties[prop.Key] = prop.Value;
            }

            return all;
        }

        /// <summary>
        /// Loads some of the entity properties from the storage
        /// </summary>
        public IList<EntityProperty> GetSome(IList<string> columns)
        {
            var some = new List<EntityProperty>();

            // Query the storage
            TableQuery query;

            if (String.IsNullOrEmpty(RowKey))
            {
                // Get entity using partition key only
                query = new TableQuery().Where(
                    String.Format("PartitionKey eq '{0}'", PartitionKey)
                    ).Select(columns);
            }
            else
            {
                // Get entity using both partition key and row key
                query = new TableQuery().Where(
                    String.Format("PartitionKey eq '{0}' and RowKey eq '{1}'", PartitionKey, RowKey)
                    ).Select(columns);
            }

            foreach (var prop in DynamicTable.Table.ExecuteQuery(query).SelectMany(
                tableEntity => tableEntity.Properties))
            {
                some.Add(prop.Value);
                _properties[prop.Key] = prop.Value;
            }

            return some;
        }

        public void Save()
        {
            DynamicTable.Table.Execute(TableOperation.InsertOrMerge(this));
        }
    }
}

DynTableEntity inherits ITableEntity to serve as a representation of a Azure table storage entity, and inherits IDictionary so as to store all its property data in a key/value dictionary for quick lookup. Not all value types are accepted by the Azure Table Storage, so we need to implement GetEntityPropertyValue() and GetEntityProperty() to properly convert to and fro. The dictionary access operators enables reading and writing a subset of entity properties; this leverages performance and lowers TCP/IP thoughput. GetAll() allows for retrieving of the whole entity with all its properties, while GetSome() retrieves a subset of entity properties only. Save() saves the entity to the associated table in the Azure table storage.

Hyper-V “driver locks” large amounts of internal memory at boot-time

Hyper-V Managment service allocates internal memory when you boot before you even think of opening any Hyper-V images.

If you only occationally use Hyper-V images then you should consider disabling the Hyper-V Managment service. Why? Well, on my Windows 8.1 RAMMap showed that 8.5 GB of my 16 GB internal memory was “Driver Locked” – the culprit was Hyper-V.

The solution is to set Hyper-V Managment service start to “Manual”, then reboot for the internal memory to be driver unlocked though – just stopping the service will not unlock and free the internal memory.