一般用 GetUserName(或 GetUserNameEx )函數可得到當前登陸登陸使用者名稱(但不總會得到,下面會分析),此系統函數在Win95、WinNT 及以後所有作業系統中都可用。代碼如下:
BOOL CSecurityTool::GetCurrProcessUser(CString& strName)
{
BOOL bRet(TRUE);
strName = _T("");
DWORD dwSize = MAX_PATH;
TCHAR *pszName = new TCHAR[dwSize];
if (!GetUserName(pszName, &dwSize))
{
delete[] pszName;
pszName = new TCHAR[dwSize];
bRet = GetUserName(pszName, &dwSize);
}
strName = pszName;
delete[] pszName;
return bRet;
}
此函數目的準確來說是擷取當前線程的使用者名稱(MSDN語:retrieves the user name of the current thread)。如果是NT service(NT服務程式)將此進程啟動,得到的結果是NT Service進程的使用者名稱,即“SYSTEM”,而不是登陸使用者名稱;同理,如果此進程是通過CreateProcessAsUser建立的,GetUserName擷取的使用者將是“AsUser”的使用者名稱。另外,如果當前線程正impersonate其他使用者環境(用函數ImpersonateLoggedOnUser可達到此目的),它擷取的將是其他使用者名稱。因此,此函數只能在特定環境中才可以擷取登陸使用者名稱。
那如何不因進程本身運行環境的不同,而準確地擷取登陸使用者名稱呢?
我們首先看看Windows XP作業系統,它提供了WTSQuerySessionInformation函數,這個函數可以擷取會話(session)相關資訊,其中一個用途是擷取會話的登陸使用者。代碼如下:
BOOL CSecurityTool::GetLogUserXP(CString& strName)
{
BOOL bRet = FALSE;
strName = _T("");
//for xp or above
TCHAR *szLogName = NULL;
DWORD dwSize = 0;
if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
WTS_CURRENT_SESSION,
WTSUserName,
&szLogName,
&dwSize))
{
strName = szLogName;
WTSFreeMemory(szLogName);
bRet = TRUE;
}
return bRet;
}