概述:调用 winsta.dll 导出接口获取系统当前登录的用户

相关枚举

typedef  enum _WINSTATIONINFOCLASS
{
	WinStationCreateData,
	WinStationConfiguration,
	WinStationPdParams,
	WinStationWd,
	WinStationPd,
	WinStationPrinter,
	WinStationClient,
	WinStationModules,
	WinStationInformation,
	WinStationTrace,
	WinStationBeep,
	WinStationEncryptionOff,
	WinStationEncryptionPerm,
	WinStationNtSecurity,
	WinStationUserToken,
	WinStationUnused1,
	WinStationVideoData,
	WinStationInitialProgram,
	WinStationCd,
	WinStationSystemTrace,
	WinStationVirtualData,
	WinStationClientData,
	WinStationSecureDesktopEnter,
	WinStationSecureDesktopExit,
	WinStationLoadBalanceSessionTarget,
	WinStationLoadIndicator,
	WinStationShadowInfo,
	WinStationDigProductId,
	WinStationLockedState,
	WinStationRemoteAddress,
	WinStationIdleTime,
	WinStationLastReconnectType,
	WinStationDisallowAutoReconnect,
	WinStationUnused2,
	WinStationUnused3,
	WinStationUnused4,
	WinStationUnused5,
	WinStationReconnectedFromId,
	WinStationEffectsPolicy,
	WinStationType,
	WinStationInformationEx
} WINSTATIONINFOCLASS;

相关结构体

typedef struct _SESSIONIDW {
	union {
		ULONG SessionId;
		ULONG LogonId;
	} _SessionId_LogonId_union;
	WINSTATIONNAME WinStationName;
	WINSTATIONSTATECLASS State;
} SESSIONIDW,
*PSESSIONIDW;
 
typedef struct _WINSTATIONINFORMATIONW {
	WINSTATIONSTATECLASS ConnectState;
	WINSTATIONNAME WinStationName;
	ULONG LogonId;
	LARGE_INTEGER ConnectTime;
	LARGE_INTEGER DisconnectTime;
	LARGE_INTEGER LastInputTime;
	LARGE_INTEGER LogonTime;
	PROTOCOLSTATUS Status;
	WCHAR Domain[DOMAIN_LENGTH + 1];
	WCHAR UserName[USERNAME_LENGTH + 1];
	LARGE_INTEGER CurrentTime;
} WINSTATIONINFORMATIONW,
*PWINSTATIONINFORMATIONW;

导出函数定义

typedef BOOL(WINAPI *pfn_WinStationEnumerateW)(_In_opt_ HANDLE hServer, _Out_ PSESSIONIDW *SessionIds, _Out_ PULONG Count);
 
typedef BOOL(WINAPI *pfn_WinStationQueryInformationW)(_In_opt_ HANDLE hServer, _In_ ULONG SessionId,
	_In_ WINSTATIONINFOCLASS WinStationInformationClass,
	_Out_writes_bytes_(WinStationInformationLength) PVOID pWinStationInformation, _In_ ULONG WinStationInformationLength,
	_Out_ PULONG pReturnLength);
typedef BOOL(WINAPI *pfn_WinStationFreeMemory)(_In_ PVOID Buffer);

获取登录用户

BOOL GetAllLoginUser(vector<CString>& vecUser)
{
	BOOL bRet = FALSE;
	static pfn_WinStationEnumerateW            pWinStationEnumerateW = NULL;
	static pfn_WinStationFreeMemory            pWinStationFreeMemory = NULL;
	static pfn_WinStationQueryInformationW     pWinStationQueryInformationW = NULL;
	static HMODULE hDll = NULL;
 
	if (pWinStationEnumerateW == NULL || pWinStationFreeMemory == NULL || pWinStationQueryInformationW == NULL)
	{
		if (hDll == NULL)
		{
#ifdef QHGetCurrentModuleHandleForCheckSign
			hDll = LoadLibrary_api_s(L"winsta.dll");
#else
			hDll = LoadLibrary(L"winsta.dll");
#endif // LoadLibrary_api_s
 
		}
 
		if (hDll)
		{
			pWinStationEnumerateW = (pfn_WinStationEnumerateW)GetProcAddress(hDll, "WinStationEnumerateW");
			pWinStationFreeMemory = (pfn_WinStationFreeMemory)GetProcAddress(hDll, "WinStationFreeMemory");
			pWinStationQueryInformationW = (pfn_WinStationQueryInformationW)GetProcAddress(hDll, "WinStationQueryInformationW");
		}
 
		if (pWinStationEnumerateW == NULL || pWinStationFreeMemory == NULL || pWinStationQueryInformationW == NULL)
		{
			return FALSE;
		}
	}
 
 
	PSESSIONIDW pTerm = NULL;
	ULONG       uTermCount = 0;
 
	/*
	DWORD dwSessionID = -1;
	BOOL bRet = ProcessIdToSessionId(GetCurrentProcessId(), &dwSessionID);
	if (bRet == FALSE)
	{
		return 0;
	}
	*/
 
	do
	{
		DWORD dwSize = sizeof(SESSIONIDW);
		bRet = pWinStationEnumerateW(NULL, &pTerm, &uTermCount);
		if (bRet == FALSE)
		{
			break;
		}
 
 
		for (ULONG i = 0; i < uTermCount; ++i)
		{
			WINSTATIONINFORMATIONW pStationInfo;
			ULONG uInfoLen = sizeof(WINSTATIONINFORMATIONW);
			ULONG uRetLen = 0;
			if (FALSE == pWinStationQueryInformationW(NULL, pTerm->_SessionId_LogonId_union.SessionId, WinStationInformation, &pStationInfo, uInfoLen, &uRetLen))
			{
				break;
			}
 
			if (pStationInfo.UserName[0])
			{
				bRet = TRUE;
				vecUser.push_back(pStationInfo.UserName);
				//wprintf(L"domain : %s, user : %s \n", pStationInfo.Domain, pStationInfo.UserName);
			}
 
			pTerm++;
		}
 
	} while (FALSE);
 
	if (pTerm)
	{
		pWinStationFreeMemory(pTerm);
	}
 
	return bRet;
}