在 Windows Servic 中通过模拟登陆获得当前激活用户的用户名

小默原创,转载请保留原文链接:http://blog.csdn.net/wshjldaxiong/article/details/8583046

该写法在XP64位下有BUG,WTSQueryUserToken 会返回 ERROR_INSUFFICIENT_BUFFER 目前无解。
#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;
}


你可能感兴趣的:(在 Windows Servic 中通过模拟登陆获得当前激活用户的用户名)