How to test if user logged in with cached credentials using LsaGetLogonSessionData function in C++

In some case it will be useful to check if users are logged in with cached credentials (for example to notify users when they have been using cached credentials to log into their laptop for too long).

The following code gets user’s last logon information with the use of LSA (Local Security Authority) API LsaGetLogonSessionData.
When cached credentials are used the LOGON_CACHED_ACCOUNT flag is set (pLogonSessionData->UserFlags & LOGON_CACHED_ACCOUNT)

#include "stdafx.h"
#include <Windows.h>
#include <Ntsecapi.h>
#include <ntstatus.h> 
#include <malloc.h>
#include <strsafe.h>

void PrintLogonType (SECURITY_LOGON_TYPE type)
{
    if (type < Interactive || type > CachedUnlock)
        _tprintf (TEXT("LogonType: UndefinedLogonType\n"));
    else {
        static LPTSTR szTypes[] = {
            TEXT("Interactive"),
            TEXT("Network"), 
            TEXT("Batch"), 
            TEXT("Service"), 
            TEXT("Proxy"),
            TEXT("Unlock"), 
            TEXT("NetworkCleartext"),
            TEXT("NewCredentials"), 
            TEXT("RemoteInteractive"),
            TEXT("CachedInteractive"),
            TEXT("CachedRemoteInteractive"),
            TEXT("CachedUnlock")
        };
        _tprintf (TEXT("LogonType: %s\n"), szTypes[(int)type-Interactive]);
    }
}


void PrintUnicodeString (LPCTSTR pszPrefix, LSA_UNICODE_STRING lsaString)
{
    if (lsaString.MaximumLength >= lsaString.Length + sizeof(WCHAR) &&
        lsaString.Buffer[lsaString.Length/sizeof(WCHAR)] == L'\0')
        _tprintf (TEXT("%s: %ls\n"), pszPrefix, lsaString.Buffer);
    else if (lsaString.Length <= STRSAFE_MAX_CCH * sizeof(TCHAR)) {
        LPWSTR sz = (LPWSTR) _alloca (lsaString.Length + sizeof(WCHAR));
        StringCbCopyNW (sz, lsaString.Length + sizeof(WCHAR), lsaString.Buffer, lsaString.Length);
        _tprintf (TEXT("%s: %ls\n"), pszPrefix, sz);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hThread = NULL;
    DWORD dwSize;
    TOKEN_STATISTICS ts;
	LUID luid;

    if(!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hThread))
	{
		wprintf(L"Error OpenProcessToken rc=0x%.8X\r\n", GetLastError());
		return -1;
	}
	dwSize = sizeof(TOKEN_STATISTICS);
    if(!GetTokenInformation (hThread, TokenStatistics, &ts, sizeof(TOKEN_STATISTICS), &dwSize))
	{
		wprintf(L"Error GetTokenInformation rc=0x%.8X\r\n", GetLastError());
		if (hThread)
            CloseHandle (hThread);
		return -1;
	}
    luid = ts.AuthenticationId;
    if (hThread)
        CloseHandle (hThread);
 
    PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
    NTSTATUS ntStatus = LsaGetLogonSessionData (&luid, &pLogonSessionData);
    if (ntStatus != STATUS_SUCCESS) {
		wprintf(L"Error LsaGetLogonSessionData rc=0x%.8X\r\n", ntStatus);
		return -1;
	}

    if (pLogonSessionData->UserName.Length)
        PrintUnicodeString (TEXT("UserName"), pLogonSessionData->UserName);
    if (pLogonSessionData->LogonDomain.Length)
        PrintUnicodeString (TEXT("LogonDomain"), pLogonSessionData->LogonDomain);
    if (pLogonSessionData->AuthenticationPackage.Length)
        PrintUnicodeString (TEXT("AuthenticationPackage"), pLogonSessionData->AuthenticationPackage);
    PrintLogonType ((SECURITY_LOGON_TYPE)pLogonSessionData->LogonType);
    _tprintf (TEXT("Session: %d\n"), pLogonSessionData->Session);

    if (pLogonSessionData->LogonServer.Length)
        PrintUnicodeString (TEXT("LogonServer"), pLogonSessionData->LogonServer);
    if (pLogonSessionData->DnsDomainName.Length)
        PrintUnicodeString (TEXT("DnsDomainName"), pLogonSessionData->DnsDomainName);
    if (pLogonSessionData->Upn.Length)
        PrintUnicodeString (TEXT("Upn"), pLogonSessionData->Upn);

	if(pLogonSessionData->UserFlags & LOGON_GUEST) wprintf(L"UserFlags=LOGON_GUEST\r\n");
	if(pLogonSessionData->UserFlags & LOGON_NOENCRYPTION) wprintf(L"UserFlags=LOGON_NOENCRYPTION\r\n");
	if(pLogonSessionData->UserFlags & LOGON_CACHED_ACCOUNT) wprintf(L"UserFlags=LOGON_CACHED_ACCOUNT\r\n");
	if(pLogonSessionData->UserFlags & LOGON_USED_LM_PASSWORD) wprintf(L"UserFlags=LOGON_USED_LM_PASSWORD\r\n");
	if(pLogonSessionData->UserFlags & LOGON_EXTRA_SIDS) wprintf(L"UserFlags=LOGON_EXTRA_SIDS\r\n");
	if(pLogonSessionData->UserFlags & LOGON_SUBAUTH_SESSION_KEY) wprintf(L"UserFlags=LOGON_SUBAUTH_SESSION_KEY\r\n");
	if(pLogonSessionData->UserFlags & LOGON_SERVER_TRUST_ACCOUNT) wprintf(L"UserFlags=LOGON_SERVER_TRUST_ACCOUNT\r\n");
	if(pLogonSessionData->UserFlags & LOGON_NTLMV2_ENABLED) wprintf(L"UserFlags=LOGON_NTLMV2_ENABLED\r\n");
	if(pLogonSessionData->UserFlags & LOGON_RESOURCE_GROUPS) wprintf(L"UserFlags=LOGON_RESOURCE_GROUPS\r\n");
	if(pLogonSessionData->UserFlags & LOGON_PROFILE_PATH_RETURNED) wprintf(L"UserFlags=LOGON_PROFILE_PATH_RETURNED\r\n");
	if(pLogonSessionData->UserFlags & LOGON_NT_V2) wprintf(L"UserFlags=LOGON_NT_V2\r\n");
	if(pLogonSessionData->UserFlags & LOGON_LM_V2) wprintf(L"UserFlags=LOGON_LM_V2\r\n");
	if(pLogonSessionData->UserFlags & LOGON_NTLM_V2) wprintf(L"UserFlags=LOGON_NTLM_V2\r\n");

	if(pLogonSessionData->UserFlags & LOGON_WINLOGON) wprintf(L"UserFlags=LOGON_WINLOGON\r\n");
	if(pLogonSessionData->UserFlags & LOGON_PKINIT) wprintf(L"UserFlags=LOGON_PKINIT\r\n");
	if(pLogonSessionData->UserFlags & LOGON_OPTIMIZED) wprintf(L"UserFlags=LOGON_OPTIMIZED\r\n");
	if(pLogonSessionData->UserFlags & LOGON_NO_OPTIMIZED) wprintf(L"UserFlags=LOGON_NO_OPTIMIZED\r\n");
 
    if (pLogonSessionData)
        LsaFreeReturnBuffer(pLogonSessionData);

	return 0;
}