另一套备用的代码,通过service调用和登陆用户交互

结合这两个东东,应该差不多可以搞定我需要的事情啦。

因为更改不了service代码,所以希望从service调用的代码里,争脱出来,和本地登陆用户进行交互启动。

#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <Tlhelp32.h>
#include <tchar.h>
#include <psapi.h>
#include <stdio.h>
#include <STDLIB.H>
#include <tlhelp32.h>
#include <WtsApi32.h>
#include <windows.h>
#include <stdio.h>
#include <Userenv.h>
#include <Wtsapi32.h>
#pragma comment(lib, "WtsApi32.lib")
#pragma  comment (lib,"psapi")
#pragma  comment (lib,"user32.lib")
#pragma  comment (lib,"advapi32.lib")
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"ws2_32.lib")

//Function to run a process as active user from windows service
void ImpersonateActiveUserAndRun()
{
    DWORD session_id = -1;
    DWORD session_count = 0;

    WTS_SESSION_INFOA *pSession = NULL;

    if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count))
    {
        printf("pSession=====%d\n", pSession);
        printf("session_count=====%d\n", session_count);
    }
    else
    {
        printf("WTSEnumerateSessions ===============failed \n");
        return;
    }
    for (DWORD i = 0; i < session_count; i++)
    {
        session_id = pSession[i].SessionId;
        printf("session_id=====%d\n", session_id);

        WTS_CONNECTSTATE_CLASS wts_connect_state = WTSDisconnected;
        WTS_CONNECTSTATE_CLASS* ptr_wts_connect_state = NULL;

        DWORD bytes_returned = 0;
        if (::WTSQuerySessionInformation(
            WTS_CURRENT_SERVER_HANDLE,
            session_id,
            WTSConnectState,
            reinterpret_cast<LPTSTR*>(&ptr_wts_connect_state),
            &bytes_returned))
        {
            wts_connect_state = *ptr_wts_connect_state;
            ::WTSFreeMemory(ptr_wts_connect_state);
            printf("wts_connect_state=====%d\n", wts_connect_state);
            // if (wts_connect_state != WTSActive) continue;
        }
        else
        {
            printf("WTSQuerySessionInformation ===============failed \n");
            continue;
        }

        HANDLE hImpersonationToken = 0;
        BOOL bRet = WTSQueryUserToken(session_id, &hImpersonationToken);
        if (bRet == false)
        {
            printf(" WTSQueryUserToken ERROR: %d\n", GetLastError());
        }
        printf("hImpersonationToken=====%d\n", hImpersonationToken);

        //Get real token from impersonation token
        DWORD neededSize1 = 0;
        HANDLE *realToken = new HANDLE;
        if (GetTokenInformation(hImpersonationToken, (::TOKEN_INFORMATION_CLASS) TokenLinkedToken, realToken, sizeof(HANDLE), &neededSize1))
        {
            CloseHandle(hImpersonationToken);
            hImpersonationToken = *realToken;
        }
        else
        {
            //log error
            continue;
        }
    }
}

bool GetSessionToken(DWORD dwSessionId, char token[256])
{
    LPTSTR pBuffer = NULL;
    DWORD dwBufferLen;
    BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSOEMId, &pBuffer, &dwBufferLen);
    if (bRes == FALSE)
    {
        return false;
    }
    lstrcpy(token ,pBuffer);
    WTSFreeMemory(pBuffer);
    return true;
}

bool GetSessionUserName(DWORD dwSessionId, char username[256])
{
    LPTSTR pBuffer = NULL;
    DWORD dwBufferLen;
    BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen);
    if (bRes == FALSE)
    {
        return false;
    }
    lstrcpy(username ,pBuffer);
    WTSFreeMemory(pBuffer);
    return true;
}

bool GetSessionDomain(DWORD dwSessionId, char domain[256])
{
    LPTSTR pBuffer = NULL;
    DWORD dwBufferLen;
    BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSDomainName, &pBuffer, &dwBufferLen);
    if (bRes == FALSE)
    {
        printf("WTSQuerySessionInformation Fail!\n");
        return false;
    }
    lstrcpy(domain,pBuffer);
    WTSFreeMemory(pBuffer);
    return true;
}

HANDLE GetProcessHandle(LPSTR szExeName)  //遍历进程PID
{
    PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
    if(Process32First(hSnapshot, &Pc))
    {
        do
        {
            if(!_stricmp(Pc.szExeFile, szExeName))
            {   //返回explorer.exe进程的PID
                printf("explorer's PID=%d\n",Pc.th32ProcessID);
                return OpenProcess(PROCESS_ALL_ACCESS, TRUE, Pc.th32ProcessID);
            }
        }while(Process32Next(hSnapshot, &Pc));
    }
    return NULL;
}

void Usage(void)
{
    fprintf(stderr,"==============================\n"
            "\tname:run programe at any session ,need system permission\n"
            "\tsession 1 D:\\callsession\\bin\\callsession.exe \n"
            "==================================\n");
}

int main(int argc, char **argv)
{
    ImpersonateActiveUserAndRun();
     //遍历所有的session
     // 函数的句柄
        HMODULE hInstKernel32 = NULL;
        HMODULE hInstWtsapi32 = NULL;
        typedef DWORD (WINAPI *WTSGetActiveConsoleSessionIdPROC)();
        WTSGetActiveConsoleSessionIdPROC WTSGetActiveConsoleSessionId = NULL;
        hInstKernel32 = LoadLibrary("Kernel32.dll");
        if (!hInstKernel32)
        {
                return FALSE;
        }
        WTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdPROC)GetProcAddress(hInstKernel32,"WTSGetActiveConsoleSessionId");
        printf("WTSGetActiveConsoleSessionId=====%d\n", WTSGetActiveConsoleSessionId);
        if (!WTSGetActiveConsoleSessionId)
        {
            return FALSE;
        }
        // WTSQueryUserToken 函数,通过会话ID得到令牌
        typedef BOOL (WINAPI *WTSQueryUserTokenPROC)(ULONG SessionId, PHANDLE phToken );
        WTSQueryUserTokenPROC WTSQueryUserToken = NULL;
        hInstWtsapi32 = LoadLibrary("Wtsapi32.dll");
        printf("WTSQueryUserToken=====%d\n", WTSQueryUserToken);
        printf("hInstWtsapi32=====%d\n", hInstWtsapi32);
        if (!hInstWtsapi32)
        {
            return FALSE;
        }
        WTSQueryUserToken = (WTSQueryUserTokenPROC)GetProcAddress(hInstWtsapi32,"WTSQueryUserToken");
        printf("WTSQueryUserToken=====%d\n", WTSQueryUserToken);

        if (!WTSQueryUserToken)
        {
            return FALSE;
        }

        //遍历3389登录的session:
        /*
        typedef struct _WTS_SESSION_INFO {
        DWORD                  SessionId;
        LPTSTR                 pWinStationName;
        WTS_CONNECTSTATE_CLASS State;
        }WTS_SESSION_INFO, *PWTS_SESSION_INFO;
        */
        WTS_SESSION_INFO *sessionInfo = NULL;
        DWORD sessionInfoCount;
        char domain1[256];
        char username1[256];
        char token1[256];
        BOOL result = WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfo, &sessionInfoCount);
        unsigned int userCount(0);
        int num=0;
        for(unsigned int i = 0; i < sessionInfoCount; ++i)
        {
            if( (sessionInfo[i].State == WTSActive) && (sessionInfo[i].State != WTSDisconnected) )
            {
                printf("session %d information:\n",num++);
                printf("\tsessionInfo.SessionId=%d\n",sessionInfo[i].SessionId);
                GetSessionDomain(sessionInfo[i].SessionId, domain1);
                printf("\tSession Domain = %s\n",domain1);
                GetSessionUserName(sessionInfo[i].SessionId,username1);
                printf("\tSession user's name = %s\n",username1);
                GetSessionToken(sessionInfo[i].SessionId,token1);
                printf("\tSession user's token = %s\n",token1);
                HANDLE hImpersonationToken;
                if (!WTSQueryUserToken(sessionInfo[i].SessionId, &hImpersonationToken))
                {
                    printf("\thImpersonationToken failed\n");
                    continue;
                }

                DWORD neededSize1 = 0;
                HANDLE *realToken = new HANDLE;
                if (GetTokenInformation(hImpersonationToken, (::TOKEN_INFORMATION_CLASS) TokenLinkedToken, realToken, sizeof(HANDLE), &neededSize1))
                {
                    CloseHandle(hImpersonationToken);
                    hImpersonationToken = *realToken;
                    printf("\thImpersonationToken token = %s\n",hImpersonationToken);
                }
                else
                {
                    printf("\tGetTokenInformation failed\n");
                    continue;
                }
                userCount++;
            }
        }
        printf("session's number:%d\n\n",userCount);

        WTSFreeMemory(sessionInfo); //释放
    if(argc==1)
    {
        Usage();

    }
    else if(argc==3) //session 1 c:\win2003\temp\klog.exe
    {
        // 得到当前登录用户的令
        HANDLE hTokenThis = NULL;
        HANDLE hTokenDup = NULL;
        HMODULE hInstKernel32 = NULL;
        HMODULE hInstWtsapi32 = NULL;
        BOOL bRes;
        DWORD dwSessionId = NULL;
        /*
        bRes = WTSQueryUserToken(dwSessionId, &hTokenDup);
        printf("WTSQueryUserToken %d\n",bRes);
        if (!bRes)
        {
            printf("WTSQueryUserToken Failed!%d\n",GetLastError());
            return FALSE;
        }

        bRes = ImpersonateLoggedOnUser(hTokenDup);
        if (!bRes)
        {
            printf("ImpersonateLoggedOnUser!%d\n",GetLastError());
            return FALSE;
        }
        MessageBox(NULL,"test2","test1",MB_OK);
        system("winver.exe");
        */

        // HANDLE hThisProcess = GetCurrentProcess(); // 获取当前进程句柄

        HANDLE   hThisProcess   = GetProcessHandle("explorer.exe");
        if(hThisProcess   ==   NULL)
                    return   0;
        printf("hThisProcess %d\n",hThisProcess);

        // 打开当前进程令牌

        OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);
        // 复制一个进程令牌,目的是为了修改session id属性,以便在其它session中创建进程
        DuplicateTokenEx(hTokenThis, TOKEN_ALL_ACCESS,NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
        //获取活动session id,这里要注意,如果服务器还没有被登录而使用了远程桌面,这样用是可以的,如果有多个session存在,
        //不能简单使用此函数,需要枚举所有session并确定你需要的一个,或者干脆使用循环,针对每个session都执行后面的代码
        dwSessionId=atoi(argv[1]); //与会话进行连接

        bRes = SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)); //把session id设置到备份的令牌中

        printf("hTokenThis: %d\n",hTokenThis);
        printf("hTokenDup: %d\n",hTokenDup);
        printf("dwSessionId: %d\n",dwSessionId);
        printf("TokenSessionId==%d\n",TokenSessionId);
        if (!bRes)
        {
             printf("SetTokenInformation!%d\n",GetLastError());
             return FALSE;
        }
        // 好了,现在要用新的令牌来创建一个服务进程。注意:是“服务”进程!如果需要以用户身份运行,必须在前面执行LogonUser来获取用户令牌
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(STARTUPINFO));
        ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
        si.cb = sizeof(STARTUPINFO);
        si.lpDesktop = "WinSta0\\Default";
        LPVOID pEnv = NULL;
        DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; // 注意标志
        //CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE); // 创建环境块
        // 创建新的进程,这个进程就是你要弹出窗口的进程,它将工作在新的session中
        char path[MAX_PATH];
       lstrcpy(path,argv[2]);
       CreateProcessAsUser(hTokenDup, NULL, (char *)path, NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &si, &pi);
    }
    else
    {
        printf("argc value is : %d", argc);
        Usage();
    }
    return 0;
}

  

时间: 2024-10-02 19:41:45

另一套备用的代码,通过service调用和登陆用户交互的相关文章

遇到很多次,要注意区分service调用,本地用户调用这些区别

  WTSQueryUserToken返回1314   The WTSQueryUserToken function obtains the primary access token of the logged-on user specified by the session ID. To call this function successfully, the calling application must be running within the context of theLocalS

Android AIDL和远程Service调用示例代码_Android

Android:AIDL和远程Service调用 本讲的内容,理解起来很难,也许你看了很多资料也看不明白,但是用起来缺简单的要命.所以我们干脆拿一个音乐播放器中进度条的实例来说明一下AIDL和Remote Service的价值和使用方法,你把这个例子跑一边,体会一下就OK了.下面的例子是我 正在准备的项目实例中的一部分. 首先说明一下我们面临的问题,如果看不懂下面的描述请看前面的课程: 第一.我们知道在AndroId中如果需要进行音乐播放,最方面的方法就是使用自带的MediaPlayer对象,如

Android AIDL和远程Service调用示例代码

Android:AIDL和远程Service调用 本讲的内容,理解起来很难,也许你看了很多资料也看不明白,但是用起来缺简单的要命.所以我们干脆拿一个音乐播放器中进度条的实例来说明一下AIDL和Remote Service的价值和使用方法,你把这个例子跑一边,体会一下就OK了.下面的例子是我 正在准备的项目实例中的一部分. 首先说明一下我们面临的问题,如果看不懂下面的描述请看前面的课程: 第一.我们知道在AndroId中如果需要进行音乐播放,最方面的方法就是使用自带的MediaPlayer对象,如

webservice-Web Service调用接口时,会校验服务端是否登录的问题,我现在不想校验登录

问题描述 Web Service调用接口时,会校验服务端是否登录的问题,我现在不想校验登录 写了一个服务端接口,客户端调用时,会验证登录,但是我这个接口就是要获取登录的相关信息,比如服务端帐套信息,我都没有帐套信息,怎么登录呢. 所以现在问题是,怎样调用取帐套信息接口不校验登录?在哪个地方可以配置呢.希望大神们指点一二! 开发环境:Jdk1.5 + Axis1.3. 服务端和客户端都是Java实现.

Android Service(不和用户交互应用组件)案例分析_Android

Service是在一段不定的时间运行在后台,不和用户交互应用组件.每个Service必须在manifest中 通过<service>来声明.可以通过contect.startservice和contect.bindserverice来启动. Service和其他的应用组件一样,运行在进程的主线程中.这就是说如果service需要很多耗时或者阻塞的操作,需要在其子线程中实现. service的两种模式 本地服务 Local Service 用于应用程序内部. 它可以启动并运行,直至有人停止了它或

Android Service(不和用户交互应用组件)案例分析

Service是在一段不定的时间运行在后台,不和用户交互应用组件.每个Service必须在manifest中 通过<service>来声明.可以通过contect.startservice和contect.bindserverice来启动. Service和其他的应用组件一样,运行在进程的主线程中.这就是说如果service需要很多耗时或者阻塞的操作,需要在其子线程中实现. service的两种模式 本地服务 Local Service 用于应用程序内部. 它可以启动并运行,直至有人停止了它或

代码-java 如何实现模拟登陆智联或者前程无忧 并且将当前帐号其中的所有发布中的职位刷新。

问题描述 java 如何实现模拟登陆智联或者前程无忧 并且将当前帐号其中的所有发布中的职位刷新. java代码, 如何实现模拟登陆智联或者前程无忧 并且将当前帐号其中的所有发布中的职位刷新.有几页刷新几页. 最好有详细代码 解决方案 下个loadrunner 全过程录一遍 是最简单的 解决方案二: 求不沉 求回答!!!!!!!!!!!!!!!!!! 解决方案三: 000000000000000

c++ opencv 分裂合并-求大神帮忙把代码改成调用opencv库的,谢谢。

问题描述 求大神帮忙把代码改成调用opencv库的,谢谢. include using namespace std; #include //需要使用堆栈,对堆栈进行操作 #include "conio.h" include "viLib.h" // 包含头文件 pragma comment( lib, "viLib.lib" ) // 包含viLib.lib库 include "viImage.h" // 包含头文件 prag

link中可以通过代码发射去调用let中定义的变量么?怎么实现?

问题描述 link中可以通过代码发射去调用let中定义的变量么?怎么实现? link中可以通过代码发射去调用let中定义的变量么?怎么实现? 解决方案 不可以,因为select以后,这些字段在select产生的匿名对象自动被提取出来了.