Saving Credentials in the Credential Manager

One of the best features of Windows is the Remote Desktop Connection software and one of the most annoying features is Windows' inability (or rather unwillingness) to use the current credential (username and password).


Yes, "Remember me" works. But it means having to type the password again and again for every server one visits and saving it for each server individually. The Remote Desktop client stores the username and password in the Windows Credential Manager.


It is possible to add a credential to the Credential Manager manually.

PS M:\> cmdkey /add:TERMSRV/telly /user:testuser /pass:password

CMDKEY: Credential added successfully.

PS M:\> cmdkey /list:TERMSRV/telly

Currently stored credentials for TERMSRV/telly:

    Target: TERMSRV/telly
    Type: Domain Password
    User: testuser

Adding to the Credential Manager programmatically is similarly simple.

Using native code, that is.

#include <Windows.h>
#include <wincred.h>

BOOL ok;
int error;

int main()
    // credential information
    LPWSTR sTargetName = L"TERMSRV/telly";
    LPWSTR sUserName = L"testuser";
    LPWSTR sPassword = L"password";
    DWORD cbCredentialBlobSize = (DWORD)(wcslen(sPassword) * sizeof(WCHAR));

    // create credential
    CREDENTIAL credential = { 0 };
    credential.Type = CRED_TYPE_DOMAIN_PASSWORD; // 2
    credential.TargetName = sTargetName;
    credential.CredentialBlobSize = cbCredentialBlobSize;
    credential.CredentialBlob = (LPBYTE)sPassword;
    credential.Persist = CRED_PERSIST_ENTERPRISE; // 3
    credential.UserName = sUserName;
    // write credential to credential store
    ok = CredWriteW(&credential, 0);
    error = GetLastError();
    wprintf(L"%d\n", error);
    return error;

It is actually a lot more complicated using managed code. The CREDENTIAL struct has to be rebuilt in managed code and the CredWriteW() API declared. The code is much longer and it is very easy to make mistakes.

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace CreateCredTestManaged
    class Program
        static bool ok;
        static int error;

        // credential struct definition as per Windows API
        struct CREDENTIAL
            public uint Flags;
            public uint Type;
            public IntPtr TargetName;
            public IntPtr Comment;
            public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
            public uint CredentialBlobSize;
            public IntPtr CredentialBlob;
            public uint Persist;
            public uint AttributeCount;
            public IntPtr Attributes;
            public IntPtr TargetAlias;
            public IntPtr UserName;

        // CredWriteW from Windows API
        static extern bool CredWriteW(
            ref CREDENTIAL Credential,
            uint Flags

        static void Main(string[] args)
            // credential information
            string sTargetName = "TERMSRV/telly";
            string sUserName = "testuser";
            string sPassword = "password";
            uint cbCredentialBlobSize = (uint)Encoding.Unicode.GetByteCount(sPassword);

            // create credential
            CREDENTIAL credential = new CREDENTIAL {
                Type = 2, // correponds to CRED_TYPE_DOMAIN_PASSWORD
                TargetName = Marshal.StringToCoTaskMemUni(sTargetName), // copies managed into unmanaged memory
                CredentialBlobSize = cbCredentialBlobSize,
                CredentialBlob = Marshal.StringToCoTaskMemUni(sPassword),
                Persist = 3, // corresponds to CRED_PERSIST_ENTERPRISE
                UserName = Marshal.StringToCoTaskMemUni(sUserName)

            ok = CredWriteW(ref credential, 0);
            error = Marshal.GetLastWin32Error(); // corresponds to GetLastError()

            Marshal.FreeCoTaskMem(credential.TargetName); // releases bytes allocated in unmanaged memory


Both programs create a credential in the Credential Manager like the cmdkey command quoted before does. It took me hours figuring it out...

ArcaOS 5.0

A new OS/2 distribution has arrived.

What's new?

  • The Arca Noae Package Manager, a frontend for yum, the "Yellowdog Updater, Modified" of Red Hat (and Yellow Dog) fame.
  • More ported UNIX and GNU software (alas no Emacs).
  • Odin is included.
  • Apparenly the icons are bigger now.

What's old and good?

  • The Sybase Watcom compiler comes as a package and is usable (but its IDE is not).
  • vi is a much better editor than epm, e and tedit.
  • Odin allows running 32 bit Windows applications.

What's ugly?

  • Still no command line shell that supports multitasking (but OS/2 had one until version 1.3 in 1991!).
  • No hex editor. No xxd.

The desktop looks like the desktop.


The "Computer" object is like Windows' "My Computer" or "This PC" icon.


I always liked the "Command Prompts" object which contained traditionally the OS/2 and MS-DOS command prompts as well as the Windows program manager seamless and stand-alone. ArcaOS adds the 4OS2 shell (which is really not great but an improvement on OS/2's cmd.exe, neither shell is even better than Windows' cmd.exe).


The OS comes with FireFox and a few other common available Internet programs. Putty also works via Odin.


Unfortunately the package manager does not offer an X server or rdesktop client so connectivity is limited to pure ssh or Telnet.

What the OS can do is run 16 bit Windows programs, the majority of them (but not, for example, Microsoft Cinemania '94). It probably runs most of the 16 bit Windows programs better than Windows Vista and above do these days.


ArcaOS also comes with Java 1.6, ultimately limiting the software that is runnable to most real mode DOS programs, most 16 bit Windows programs, some 32 bit x86 Windows programs, all (i.e. the few existing) 16 and 32 bit OS/2 programs and 32 bit Java programs up to version 1.6 of the platform.

Coins from the Mandate Period

These are a few (essentially worthless) coins I picked up.

The first three are from the French Mandate of Syria. Lebanon had just been split from the territory and the two countries under French control became l'Etat de Syrie and 'Etat du Grand Liban. (The letter is "grand" because today's Lebanon includes some regions around the original Libanon as well.)

WP 20170514 22 45 06 Rich

And these are coins from the British Mandate of Israel/Palestine. (I don't know how they dealt with Iraq currency-wise.)

The currency was the Palestine Pound which was equal to the British Pound but was decimalised. Instead of 12 pence to the shilling and 20 shillings to the pound, the currency was subdivided into 1000 "mils" ("milim" in Hebrew). Note that 1 pound in 1942 was approximately the equivalent of 40-50 pounds today and hence 2 mils were a usable 10 New Pence.

WP 20170514 22 45 58 Rich

Bank notes existed as well (printed by a private bank in London) but I don't have any here.

A few years after independence the "Palestine Pound" was hebraised and became the "Israeli Lira" (with "lira" being the Italian word for "pound" used by the Ottoman Empire) and was then finally replaced by the (even more hebraised) Israeli Shekel (with "shekel" being the Hebrew word for a certain weight less than a pound) and the Israeli New Shekel.

Israeli Lira had the adorable socialist paradise look fashionable in the 1950s.

WP 20170514 23 14 25 Rich

WP 20170514 23 09 58 Rich

The strong, happy labourer (with a moustache and otherwise clean-shaven, not religious) and the female farmer (also strong and happy) were now in power.

The obverse of the notes showed artefacts from Israelite history and the words "Bank of Israel" in Hebrew, Arabic and English.

WP 20170514 23 14 39 RichWP 20170514 23 10 29 Rich

QNAP TS-451+

I bought a QNAP TS-541+ NAS. It came with 8 GB RAM and I added an 8 TB hard drive and a 500 GB SSD.

After downloading the QFinder tool the NAS configured itself and finally showed this Web interface.


The interface is quite snappy and works really really well. In fact I haven't seen a Web interface as well-done as this ever before. (Citrix XenApp comes close but is not nearly as pretty.)


So far I found you can create users and groups, shares (SMB, AFP, and NFS), and an FTP server. The NAS also acts as a Web server and can be a VPN server or even a (apparently Windows-compatible) domain controller.

Each user has a home directory. Only the "admin" user can log in via ssh (or Telnet, if enabled). The su and sudo commands are missing.


The NAS also supports the creation of virtual machines. I think it uses KVM.


There are a lot of apps and features I didn't even try or look at yet.

So far I recommend the device fully.

Could not connect to one or more vCenter Server systems

Very very very often vCenter 6.5 will greet me with the helpful message "Could not connect to one or more vCenter Server systems". It turns out this is a bug in vCenter 6.5.

To recover vCenter, I had to follow these simple few steps.

1. Secure shell into the vCenter appliance and open the vpxd log file.


2. In it, find error messages at the end that look like this.

error vpxd[7F0A533E7700] [Originator@6876 sub=vpxCommon opID=HostSync-host-19-795056c4] [Vpxd_HandleVmRootError] Received unrecoverable VmRootError. Generating minidump ...

error vpxd[7F0A533E7700] [Originator@6876 sub=Default opID=HostSync-host-19-795056c4] An unrecoverable problem has occurred, stopping the VMware VirtualCenter service. Error: Error[VdbODBCError] (-1) "ODBC error: (23505) - ERROR: duplicate key value violates unique constraint "pk_vpx_vm_virtual_device";


3. Open the postgresql log file (use ls -trl to find the current one, check the last two or three).


4. Find the corresponding (to the above errors) entry. It looks like this.

VCDB vc ERROR:  duplicate key value violates unique constraint "pk_vpx_vm_virtual_device"

VCDB vc DETAIL:  Key (id, device_key)=(101, 3002) already exists.


5. Make a not of the id and device_key (here 101 and 3002).

6. Start the psql client and connect as the postgres user. (Apparently no password is needed.)

/opt/vmware/vpostgres/current/bin/psql -U postgres

7. Switch to the VMware database. Note the case sensitivity.


You can also show the tables in the database using


8. Show the offending device entry. Use the ID and DEVICE_KEY found above.

SELECT * FROM vpx_vm_virtual_device WHERE ID=101 AND DEVICE_KEY=3002;

9. If the device looks like it could be the offender (perhaps it is an externally connected USB device), go ahead and delete it (but don't blame me if this goes horribly wrong).

DELETE FROM vpx_vm_virtual_device WHERE ID=101 AND DEVICE_KEY=3002;

10. Reboot the vCenter appliance.

Also see

Visual Studio 2017 First Look

Visual Studio 2015 used up lots of disk space, all on drive C:, regardless of where and what one chose to install it. Visual Studio 2017 is a lot more modular. Visual Studio 2017 also appears to have integrated Xamarin as well as third-party tools.


The Windows section of the installer offers three ways to develop for Windows.


Universal Windows Platform development targets Windows 10, Windows Server 2016 Desktop Experience, Windows 10 IoT Core, and Windows 10 Mobile. It supports both .NET languages and C++. I am guessing Windows 8 support is long forgotten for good reason.


Desktop development with C++ targets all versions of Windows that support Win32 applications down to Windows XP.


.NET desktop development targets all versions of Windows that support .NET Framework 4.0 and above, i.e. Windows Server 2003 and Windows Vista and above. It does not target but can also be used for versions of Mono that support .NET Framework 4.0 and above on Mac OS, GNU/Linux and other platforms supported by Mono.


The Web & Cloud section offers a motley collection of features, some of which target the Web, some of which target Microsoft's cloud Azure, and some of which target all sorts of other things.


ASP.NET and web development provides a Web framework for .NET. It targets Internet Information Server on Windows. It does not specifically target but might work with Mono.


Node.js development appears to be a JavaScript environment of some kind.


Office/SharePoint development contains tools for Office and SharePoint development, which Microsoft apparently consider "Web" and "Cloud".


Whereas Azure development actually is Microsoft's cloud and Visual Studio provides utilities and build tools.


And I assume Data storage and processing is a collection of programming tools for SQL Server and Azure Data Lake.


Mobile & Gaming provides tools for mobile and game development, as the name might suggest.


Mobile development with .NET is really Xamarin and contains .NET libraries to support statically-linked targeting (with the Xamarin libraries) of iOS, Android and Universal Windows Platform.


Mobile development with JavaScript I guess supports mobile development with JavaScript using Apache Cordova.


Game development with C++ contains C++ libraries for game development for DirectX and the Unreal engine.


Game development with Unity contains Visual Studio support for the Unity game development framework for .NET.


Mobile development with C++ targets native iOS and the Android NDK.


Other Toolsets is everything Microsoft didn't want to sort into the above categories, although it would fit.


Visual Studio extension development is the SDK for Visual Studio itself.


.NET Core cross-platform development targets all .NET Core platforms including Windows 10, Windows Server 2016, Windows Server 2016 Server Core, Windows Server 2016 Nano Server, Windows 10 IoT Core, Windows 10 Mobile, GNU/Linux and Mac OS. It presumably also works with Mono platforms.


Linux development with C++ targets GNU/Linux using a Microsoft compiler and C runtime library.

All-in-all Visual Studio 2017 appears to be a return to CP/M times at Microsoft. Instead of supporting Microsoft platforms only, Microsoft have returned to trying to develop the best developer tools for Microsoft and non-Microsoft platforms. (After all, Microsoft have started as a developer tools company.)

Microsoft do not provide an ISO or even an offline installer. But such a beast can be created by running the provided online installer in a special mode.

Microsoft explain here how to create an offline installer for Visual Studio 2017.

tl;dr vs_enterprise.exe --layout C:\vs2017offline --lang en-US creates a Visual Studio 2017 offline installer in c:\vs2017offline. Replace vs_enterprise.exe with the appropriate name for the installer you have.

IBM PC Boot Loader - Reading the Root Directory

A FAT12 file system's directory consists of a number of 32 bit long entries. The first 11 characters of each entry are the file name (8 characters) and file type (3 characters).

Mounted as a -t msdos in Linux it looks like this.


On the disk, as seen in a hex editor, it looks like this.


Note that file names shorter than 8 characters are actually 8 characters long with the missing characters filled with spaces (ASCII 0x20).

Returning to the existing boot loader, with the variable names updated because I felt like it. This is the new beginning of the boot sector.


As noted in earlier blog entries this code is loaded at address 0x7C00. The root directory has to be loaded somewhere too (and later the FAT). There is also need for a stack segment (which here starts at 0x6C00 some 4 KB before the code).


Remember that segment registers are extended by a nybble (half a byte). Hence 0x6C0 in a segment register equals the segment base address 0x6C00. (In order not to be confused I start the names of offsets with a "p" and the names of segment addresses with "a".)

The boot loader main routine configures the segment registers (code = data = extra, stack at 0x6C00) and defines a stack of 4 KB. It then proceeds to print "hello" before calling the loaddir and findfile routines and ending the program with printing "bye" before rotating forever.


The loaddir routine loads the disk's root directory at address 0x7E00. The root directory is 14 sectors long and starts at sector 19.

The IBM 3.5" 1.44 MB floppy disk has 80 tracks and 18 sectors per track. (It also has two sides, if you can believe it.) The fact that the root directory is located right at the beginning of a track and is shorter than the track allows reading it with little calculation and in one move.

Sector 19 is the second sector of the second side of the first track.

Tracks are zero-based. Hence the first track is track 0. This goes into CH.

Sectors are one-based. Hence the second sector is sector 2. Goes into CL.

Disk sides are zero-based. Hence the second side is side 1. Goes into DH.

There is only one drive. Drives are zero-based. Drive 0 goes into DL.

This routine uses hard-coded block addresses. (I think this is appropriate since the geometry of the disk was known when the boot sector was written. It's also easier to write. The routines for calculating logical block addresses from physical addresses and vice versa explained in a previous entry are not being used.)


After loading the root directory at address 0x7E00 each entry needs to be read and compared to the name of the file that needs loading. This is as far as this goes for now.


This routine displays the file name and type it finds when comparing each directory entry with the image file name. (Ultimately it should of course load the file and far jump into the newly loaded code.)

The accumulator (AX) is initialised with 0 to be used as an offset, the counter (CX) with the number of root directory entries (224). The source index (SI) is initialised with the address of the image file name and the destination index is initialised with the address of the root directory in memory (0x7E00).

At this point the loop starts.

The current directory entry is at DI+AX. The relevant part of the entry is the first 11 bytes, the file name (8 bytes) and the file type (3 bytes). This is compared with the image file name. The string comparison is done using a special x86 instruction for string comparisons that uses the SI and DI registers (which are already filled correctly) and the CX register (which therefor has to be saved before and restored after the string comparison). The string comparison is to be done on 11 characters, hence CX is initialised with 11.

If the two 11-character strings are equal, the file is found and its name displayed on the screen. There happens to be a zero following the file name. This is because byte 11 is the attribute byte and there are no attributes set. I am using this fact so I can use my writes routine which prints zero-terminated strings.

When running, it looks like this.


Note that there is no carriage return and line feed following the file name and file type output.

To be continued...

Data Types and Pointer Sizes

Because I was bored and because boring repetetive tasks interest me greatly, I wrote a little program that displays data type sizes and compiled it for a variety of platforms immediately available to me.

This is the program.

#include <stdio.h>

int main()
    char *s = ""
        "\nType sizes of current architecture and system\n"
        "char: %d\n"
        "short: %d\n"
        "int: %d\n"
        "long: %d\n"
        "long long: %d\n"
        "float: %d\n"
        "double: %d\n"
        "long double: %d\n"
        "pointer: %d\n\n";
        sizeof(long long)*8,
        sizeof(long double)*8,
        sizeof(char *)*8

It does absolutely nothing useful, only displays the sizes, in bits, of various data types (the last one being a char pointer).

The first three compiled versions were for 32 bit Windows NT (x86 and ARM) and 64 bit Windows NT (AMD64).



The first binary tells us that in 32 bit Windows NT (Windows 10 in this case), a byte is 8 bits long (this is true for all the platforms involved here), an int is a long is 32 bits and a long long is 64 bit. Pointer size of 32 bit Windows NT is, you guessed it, 32 bits.

Windows NT on ARM works exactly the same way. 8 bit bytes, 16 bit shorts, 32 bit ints and longs and 64 bit long longs plus 32 bit pointers.

Note the 64 bit long double floating point type which is identical with the 64 bit double type for all Windows platforms.


64 bit Windows NT simply has a greater pointer size, the most unexpected 64 bit for the 64 bit operating system.

This is called the LLP64 or IL32P64 data model and is used by Windows NT on AMD64 and Itanium.

But on the other hand it should be noted that UNIX, represented here by the favourite Unix clone GNU/Linux, uses 64 bit longs (and 128 bit long doubles). Pointer size is also 64 bit. This is called the LP64 or I32LP64 data model and is used by various operating systems including most UNIX derivatives and clones.

Back in the PC world 32 bit OS/2 just like 32 bit Windows NT. This is of course not a coincidence. Windows NT started its career as Microsoft's planned replacement for OS/2.


OS/2 was a weird 16-32 bit hybrid and also supported 16 bit software.


A 16 bit OS/2 executable lives in a 16 bit world, with 16 bit ints and 16 bit pointers. This is a segmented architecture. While pointers were 16 bit it was possible to address significantly more memory than 64 KB in total.

Note the traditional Windows and OS/2 identity of double and long double.

MS-DOS (note the 8.3 file name) provided (or existed in) a similar environment. The difference was that OS/2's memory addresses were not real. Again this is a segmented architecture.


OpenVMS on Alpha uses the same data model as Windows NT. 64 bit VMS appeared before Windows NT which at the time ran on the Alpha CPU but in 32 bit mode.

But note that OpenVMS does not adhere to the Windows and OS/2 tradition of identical double and long double types.


It is possible on OpenVMS to create a 32 bit executable. This doesn't seem to impact the other data types. I am not sure what it really means.


Note the fact that OpenVMS file names are case-insensitive and cannot contain dots. (Like in MS-DOS the dot separates the file name from the file type specifier. This is actually a good idea.)


I want to introduce my friend VereMolf.


Further details might follow.

Windows Registry Keys - A Growing List

This blog entry is the beginning (and continuation) of a growing list of Windows Registry Keys about which I had reason to know or in which I had to modify values.

I try to keep them sorted in roughly alphabetical order, not counting \WOW6432Node.


  • HKLM:\SOFTWARE\WOW6432Node\Citrix\ICA Client\
  • REG_DWORD VdLoadUnLoadTimeOut
  • VdLoadUnLoadTimeOut sets a connection timeout in seconds. Set to something large (10 seconds) to avoid "This version of Citrix Receiver does not support selected encryption" errors which are apparently triggered by Receiver deciding that that must be the case for the connection not finishing. (Found in Citrix Knowledge Center CTX133536.) Why this is a hard-to-find registry value and not simply enabled by default is a Citrix mystery.

  • HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\
  • Configures Limited User Account (User Account Control). 0 disables LUA, 1 enables LUA. Explained here in the Microsoft Developer Network. Check that article for further options.

  • HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\
  • REG_DWORD Disabled
  • Set to 1 to disable Windows Error Reporting. (That's the annoying discussion Windows starts after an application crashes.)

  • HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList\
  • REG_DWORD UserName
  • UserName can be any user name. Set its data to 0 to hide the user from the login screen. (You can still log on as that user by typing his name.)

  • HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer\
  • REG_DWORD DisableNotificationCenter
  • Set to 1 to disable the annoying "Notification Center".

  • HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\
  • REG_SZ SusClientID
  • Used by Windows Server Update Services (WSUS) to identify the computer. Reset by stopping the wuauserv service (1), deleting the property (2), starting the wuauserv service (2), and forcing Windows Update to reinitialise on the server (4).
  • 1: Stop-Service wuauserv
  • 2: Remove-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate SusClientID
  • 3: Start-Service wuauserv
  • 4: wuauclt /resetauthorization /detectnow

  • HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU\
  • REG_DWORD AUOptions
  • Configures Windows Update. (Explained here in the Microsoft Developer Network.) 1 actually disables automatic updates, This allows users to choose themselves when to check for and download updates.


  • HKLM:\SYSTEM\CurrentControlSet\Control
  • REG_DWORD ServicesPipeTimeout
  • Apparently this configures the time services have to react and start. Default might be 30 seconds (30000 decimal). Given in milliseconds.

 © Andrew Brehm 2016