源码 获得系统进程快照以及对应的用户名

来源:互联网 发布:数控模拟软件 编辑:程序博客网 时间:2024/06/10 08:16
由于手头上有个项目, 需要获得系统进程快照,并且要求能够获得系统的进程用户名,所以写了下试验函数,源码如下, 其中对OpenProcessToken函数失败的情况未进行进一步处理,而只是粗略的认为其为系统进程。其Release版本已经在WIN2000、XP、2003下测试成功,欢迎大家给予错误指定。


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <Winbase.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>

#include "Tlhelp32.h"



/************************************************************************/
/* 根据进程ID获得进程用户名                                                                    */
/* 成功返回0, 失败返回-1                                                                            */
/************************************************************************/
int PrintUserName(DWORD ProcessId, char *pUserName, int StrLen)
{
    HANDLE hToken = NULL;
    BOOL TokenRet = false;
    PTOKEN_USER   pTokenUser = NULL;
    DWORD   cb = 0;
    SID_NAME_USE  snu;
    char  domain[1024];
    DWORD   cbdomain = 1023;

    memset(domain, 0, sizeof(domain));
    
    //PROCESS_QUERY_INFORMATION方式打开进程
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, ProcessId);
    if(!hProcess)
    {
        fprintf(stderr, "OpenProcess PROCESS_QUERY_INFORMATION方式 失败,GetLastError()=%d/n", GetLastError());
        return -1;
    }
    
    //获得进程的令牌句柄,进行信息查询
    TokenRet = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
    if(!TokenRet) //如果失败
    {
        //关闭之前的句柄
        if (hProcess)
        {
            CloseHandle(hProcess);
            hProcess = NULL;
        }

        //更换打开权限方式
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, ProcessId);
        if(!hProcess)
        {
            fprintf(stderr, "OpenProcess PROCESS_ALL_ACCESS 方式失败,GetLastError()=%d/n", GetLastError());
            goto ERRORRETURN;
        }

        //重新获得进程的令牌句柄,进行信息查询
        TokenRet = OpenProcessToken(hProcess,TOKEN_QUERY,&hToken);
        if(!TokenRet)
        {
            fprintf(stderr, "/nOpenProcessToken 打开失败,GetLastError()=%d/n", GetLastError());
            goto ERRORRETURN;
        }
    }

    //获得信息的长度
    TokenRet = GetTokenInformation(hToken, TokenUser/*TokenOwner*/, NULL, cb, &cb);
    if(!TokenRet)
    {
        DWORD dwResult = GetLastError();
        if ( dwResult != ERROR_INSUFFICIENT_BUFFER)
        {
            fprintf(stderr, "GetTokenInformation 失败,GetLastError()=%d/n", GetLastError());
            goto ERRORRETURN;
        }
    }

    //申请结构体空间
    pTokenUser = (PTOKEN_USER) GlobalAlloc(GPTR, cb);
    if (!pTokenUser)
    {
        fprintf(stderr, "GlobalAlloc 失败,GetLastError()=%d/n", GetLastError());
        goto ERRORRETURN;
    }

    //获得信息
    TokenRet = GetTokenInformation(hToken, TokenUser/*TokenOwner*/, pTokenUser, cb, &cb);

    //获得进程用户名
    TokenRet = LookupAccountSid(NULL,pTokenUser->User.Sid/*pto-> Owner*/
        , pUserName, (unsigned long *)&StrLen, domain, &cbdomain, &snu);
    if(!TokenRet)
    {
        goto ERRORRETURN;
    }

    //释放结构体空间
    if (pTokenUser)
    {
        GlobalFree(pTokenUser);
        pTokenUser = NULL;
    }

    //关闭句柄
    if (hToken)
    {
        CloseHandle(hToken);
        hToken = NULL;
    }

    //关闭句柄
    if (hProcess)
    {
        CloseHandle(hProcess);
        hProcess = NULL;
    }

    return 0;

//错误处理
ERRORRETURN:
    
    //释放结构体空间
    if (pTokenUser)
    {
        GlobalFree(pTokenUser);
        pTokenUser = NULL;
    }

    //关闭句柄
    if (hToken)
    {
        CloseHandle(hToken);
        hToken = NULL;
    }
    
    //关闭句柄
    if (hProcess)
    {
        CloseHandle(hProcess);
        hProcess = NULL;
    }
    
    return -1;
}



int main()
{
    HANDLE hSnapShot = NULL;
    BOOL bRet = FALSE;
    PROCESSENTRY32 pEntry;
    struct _timeb tstruct1, tstruct2;
    char ProceUserName[100];
    int Retcode = 0;

    memset(&pEntry, 0, sizeof(pEntry));
    memset(ProceUserName, 0, sizeof(ProceUserName));

    //获得初始时间
    _ftime(&tstruct1);

    //给定大小
    pEntry.dwSize = sizeof(pEntry);

    //获得系统快照
    hSnapShot = CreateToolhelp32Snapshot (TH32CS_SNAPALL, NULL);
    if (hSnapShot == INVALID_HANDLE_VALUE)
        return -1;

    //获得第一个进程
    Process32First(hSnapShot, &pEntry);
    for(;;)
    {
        //获得下一进程
        BOOL hRes=Process32Next (hSnapShot,&pEntry);
        
        if(hRes == FALSE)
            break;
        
    
        
        //获得进程用户名
        Retcode = PrintUserName(pEntry.th32ProcessID, ProceUserName, sizeof(ProceUserName)-1);
        if (Retcode != 0)
        {
            sprintf(ProceUserName, "SYSTEM");
        }
        printf("%s/t", pEntry.szExeFile);
        printf("%s/t", ProceUserName);
//        printf("%d/t", pEntry.th32ProcessID);
//        printf("%d/t", pEntry.cntThreads);
        printf("/n");
        
    }
    
    if (hSnapShot)
    {
        CloseHandle (hSnapShot);
        hSnapShot = NULL;
    }

    _ftime( &tstruct2 );

    //打印时间
    if (tstruct2.time == tstruct1.time)
        printf( "使用时间 milliseconds:/t/t/t%d/n", tstruct2.millitm - tstruct1.millitm);
    else if (tstruct2.time > tstruct1.time)
    {
        printf( "使用时间 milliseconds:/t/t/t%d/n"
            , tstruct2.time*1000 -  tstruct1.time*1000 + tstruct2.millitm - tstruct1.millitm);
    }


    return 0;
}
原创粉丝点击