#include <Wtsapi32.h> static int GetCurrentUserName(char *szBuf, DWORD dwRet) { HANDLE token, ph = NULL; DWORD SeId;//pid int ret = 0; if(dwRet < MAX_PATH) { ret = -1; goto END; } SeId = WTSGetActiveConsoleSessionId(); if(WTSQueryUserToken(SeId, &token) == 0) { MyDebugPrint("WTSQueryUserToken failed (%lu)\r\n", GetLastError()); ret = -5; goto END; } if(ImpersonateLoggedOnUser(token) == 0) { MyDebugPrint("ImpersonateLoggedOnUser failed (%lu)\r\n", GetLastError()); ret = -6; goto END; } GetUserName(szBuf, &dwRet); RevertToSelf(); END: if(token) { CloseHandle(token); } if(ph) { CloseHandle(ph); } return ret; }
另有利用 explorer.exe 进程进行模拟登陆的方式,但并不总是可靠,在 Service 首次安装运行时,有可能仍然拿到的是管理员的用户名。
DWORD FindProcessByName(char *ProcessName) { HANDLE hHandle; BOOL Next; char szName[MAX_PATH]; PROCESSENTRY32 p32 = {sizeof(p32)}; hHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(INVALID_HANDLE_VALUE == hHandle) { MyDebugPrint("CreateToolhelp32Snapshot failed (%lu)\r\n", GetLastError()); return 0; } Next = Process32First(hHandle, &p32); while (Next) { wsprintf(szName, "%s", p32.szExeFile); if (lstrcmpi(szName, ProcessName) == 0) { return p32.th32ProcessID ; } Next = Process32Next(hHandle, &p32); } CloseHandle(hHandle); return 0; } int GetCurrentUserName(char *szBuf, DWORD dwRet) { HANDLE token, ph = NULL; DWORD SeId;//pid int ret = 0; if(dwRet < MAX_PATH) { ret = -1; goto END; } pid = FindProcessByName("explorer.exe"); if(pid == 0) { ret = -2; goto END; } ph = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if(NULL == ph) { MyDebugPrint("OpenProcess failed (%lu)\r\n", GetLastError()); ret = -3; goto END; } if(!OpenProcessToken(ph, TOKEN_QUERY | TOKEN_DUPLICATE, &token)) { MyDebugPrint("OpenProcessToken failed (%lu)\r\n", GetLastError()); ret = -4; goto END; } if(ImpersonateLoggedOnUser(token) == 0) { MyDebugPrint("ImpersonateLoggedOnUser failed (%lu)\r\n", GetLastError()); ret = -5; goto END; } GetUserName(szBuf, &dwRet); RevertToSelf(); END: if(token) { CloseHandle(token); } if(ph) { CloseHandle(ph); } return ret; }