callsession新功能版

可以getopt解析参数。

也实现了将参数用空格分隔,来传给进程。

注意string和LPSTR数据类型的转换方法:

LPSTR(lpCmdLine.c_str())

 

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <Userenv.h>
#include <Wtsapi32.h>
#pragma comment(lib, "WtsApi32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "userenv.lib")
using namespace std;

#define EPR                 fprintf(stderr,
#define ERR(str, chr)       if(opterr){EPR "%s%c\n", str, chr);}
int     opterr = 1;
int     optind = 1;
int    optopt;
char    *optarg;

int getopt (int argc, char *const argv[], char *opts)
{
    static int sp = 1;
    int c;
    char *cp;

    if (sp == 1)
        if (optind >= argc ||
           argv[optind][0] != '-' || argv[optind][1] == '\0')
            return -1;
        else if (strcmp(argv[optind], "--") == 0) {
            optind++;
            return -1;
        }
    optopt = c = argv[optind][sp];
    if (c == ':' || (cp=strchr(opts, c)) == 0) {
        ERR (": illegal option -- ", c);
        if (argv[optind][++sp] == '\0') {
            optind++;
            sp = 1;
        }
        return '?';
    }
    if (*++cp == ':') {
        if (argv[optind][sp+1] != '\0')
            optarg = &argv[optind++][sp+1];
        else if (++optind >= argc) {
            ERR (": option requires an argument -- ", c);
            sp = 1;
            return '?';
        } else
            optarg = argv[optind++];
        sp = 1;
    } else {
        if (argv[optind][++sp] == '\0') {
            sp = 1;
            optind++;
        }
        optarg = 0;
    }
    return c;
}

HANDLE GetUserToken(DWORD dwSessionId)
{
    HANDLE hImpersonationToken = 0;
    if (!WTSQueryUserToken(dwSessionId, &hImpersonationToken))
    {
        printf(" WTSQueryUserToken ERROR: %d\n", GetLastError());
        return FALSE;
    }
    DWORD dwNeededSize = 0;
    HANDLE *realToken = new HANDLE;
    TOKEN_USER *pTokenUser = NULL;
    PTOKEN_GROUPS pGroups = NULL;
    //twice call function
    if (!GetTokenInformation(hImpersonationToken, TokenUser, NULL, 0, &dwNeededSize))
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && dwNeededSize > 0)
        {
            pTokenUser = (TOKEN_USER*)new BYTE[dwNeededSize];
            if (!GetTokenInformation(hImpersonationToken, TokenUser, pTokenUser, dwNeededSize, &dwNeededSize))
            {
                printf("GetTokenInformation ERROR: %d", GetLastError());
            }
        }
        return hImpersonationToken;
    }
    return hImpersonationToken;
}

bool GetSessionUserName(DWORD dwSessionId, char username[256])
{
    LPTSTR pBuffer = NULL;
    DWORD dwBufferLen;
    if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen))
    {
        printf(" WTSQuerySessionInformation ERROR: %d\n", GetLastError());
        return FALSE;
    }
    lstrcpy(username ,pBuffer);
    WTSFreeMemory(pBuffer);
    return TRUE;
}

void Usage(void)
{
    printf("**********************usage******************\n");
    printf("USAGE: path:\\callsession.exe sxxxn path-exe-file arg1 arg2 arg3 ... \n");
    printf("**********************usage******************\n");
}

int main(int argc, char** argv)
{
    if(argc == 1)
    {
        Usage();
        return FALSE;
    }
    else if(argc > 1)
    {

        int c;

        while ((c = getopt(argc, argv, "MNOVv+I:D:U:F:lg")) != -1)
            switch (c) {
            case 'N':

                break;
            case 'I':
                puts(optarg);

                break;
            case 'D':
            case 'U':
                puts(optarg);
                break;
            case 'M':

                break;
            case 'v':

                break;
            case 'V':

                break;
            case '+':

                break;
            default:
                break;
            }
        */
        int i;
        string lpCmdLine = "";
        LPSTR lpUsername;
        DWORD session_id = -1;
        DWORD session_count = 0;
        WTS_SESSION_INFOA *pSession = NULL;
        char username[256];
        BOOL blFound = FALSE;
        lpUsername = argv[1];
        // add all $2 $3 $4 $5 ... as second argument to program.
        for (i=2; i < argc; i++)
        {
            // printf("argument %d is %s.\n", i, argv[i]);
            lpCmdLine += argv[i];
            lpCmdLine += " ";
        }
        // printf("argument is %s\n", lpCmdLine);

        //EnumerateSessions
        if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count))
        {
            printf("WTSEnumerateSessions ERROR: %d", GetLastError());
            return FALSE;
        }
        //Get the right user and his session id
        for(DWORD i = 0; i < session_count; ++i)
        {
            GetSessionUserName(pSession[i].SessionId,username);
            //if( (pSession[i].State == WTSActive) && (pSession[i].State != WTSDisconnected) )
            if(!strcmp(lpUsername, username))
            {
                printf("\tSession user name = %s\n",username);
                session_id = pSession[i].SessionId;
                printf("\tsession_id = %d\n",session_id);
                blFound = TRUE;
                break;
            }
        }
        if (!blFound){
            printf("No login username %s found.", lpUsername);
            return FALSE;
        }
        WTSFreeMemory(pSession); //free meme heap
        //Duplicate User Token
        HANDLE hTokenThis = GetUserToken(session_id);
        HANDLE hTokenDup = NULL;
        if (!DuplicateTokenEx(hTokenThis, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hTokenDup))
        {
            printf("DuplicateTokenEx ERROR: %d\n", GetLastError());
            return FALSE;
        }
        if (!SetTokenInformation(hTokenDup, TokenSessionId, &session_id, sizeof(DWORD)))
        {
             printf("SetTokenInformation Error === %d\n",GetLastError());
             return FALSE;
        }
        //init this process info
        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);
        if (!CreateProcessAsUser(hTokenDup, NULL, LPSTR(lpCmdLine.c_str()), NULL, NULL, FALSE, dwCreationFlag, NULL, NULL, &si, &pi))
        {
            printf("CreateProcessAsUser Error === %d\n",GetLastError());
            return FALSE;
        }
        printf("%s--%s--%s", lpUsername, LPSTR(lpCmdLine.c_str()), "OK");
    }

    return 0;
}

  

 

时间: 2024-09-15 15:59:42

callsession新功能版的相关文章

Dreamweaver 8 BETA2版新功能图文快报

dreamweaver Dreamweaver 8 目前正处于全球APLHA内测期间,以下内容来自BETA2版对Dreamweaver 8新功能的图文解释. 1.Dreamweaver 8 画面截图: 2,新建文档对话框,注意具有了XSLT的选项(同时新建的文档类型默认为XHTML 1.0 Transitional) 3,还有"Starter Pages"提供选择 4,建立XSLT,可视化操作XML数据源(另外,默认页面设计视图具有标尺) 5,统一的CSS面板 6,CSS渲染,打开后才

使用.net framework中常用类在2.0版中的新功能

在上一篇<浏览.NET Framework 2.0 类型库中新增的常用功能>一文中我主要列了几个新增的常用主件,本文作为小结主要针对一些常用类的扩展来讲最近在使用C# 2.0 的时候发现的几个新特征,讲得不当之处请网友指正. 1.Exception异常基类在2.0下,Exception基类增加了Data属性,原型如下,public virtual IDictionary Data {get;}可见其实现了IDictionary接口,用来存储异常的自定义信息,由此想到在ExceptionMana

QQ 2013云消息记录版新功能

腾讯已推出了QQ2013云消息记录版体验版本,漫游消息升级为云消息,并与本地消息合并,让你即使在多个终端使用QQ也能便捷地查阅和管理消息记录.体验时间:2013年10月14日 - 2013年10月26日 体验详情 QQ2013云消息记录版新功能: =================================== 1.漫游消息升级为云消息,并与本地消息合并: 2.支持各个终端,各个版本QQ的消息记录储存到云端: 3.简化了查看云消息时独立密码的验证操作. 申请地址:http://exp.qq

QQ邮箱2007贺岁版新功能介绍

新的QQ邮箱2007贺岁版昨天隆重登场.和之前的QQQQmail3.0相比,新版QQ邮箱最大的特点是:速度更快,读写界面更大,功能更加个性化.而更人性的细节设计让您在使用过程中倍感体贴,在尽享愉悦舒心视觉体验的同时,也将您与众不同的个性logo彰显无遗. 快去感受一下QQ邮箱贺岁版所带来的非凡体验吧! http://mail.qq.com 1.彩色邮件主标题 QQ邮箱独有的新功能.写信时,可以随意设置主题的文字颜色,让收信人对方更能注意到您你的"多姿多彩".! 2.元旦logo更新,增

WPS Office 2013抢鲜版有哪些新功能?

我们来看看WPS 2013有什么新功能新亮点吧? 第一次打开WPS2013时会弹出介绍 我们先来看看WPS2013的官方介绍有啥新亮点. 目前WPS2013已经正式支持Linux平台,功能也基本完善,而iOS平台上WPS功能依然较弱.总的来说,WPS2013基本上完成了对移动和PC版两大平台的支持. 多平台支持 WPS2013的新组件--轻办公,能让你跟同事在一个圈子里共同敲改文档方案,这功能后面有详细介绍,这里简单略过. WPS2013轻办公 在WPS2012崛起的时候,WPS就有三大亮点,一

UC浏览器pc版3.0有哪些新功能?

  近日uc浏览器电脑版更新至3.0了,既然是更新那么一定有些新功能加入.UC浏览器pc版3.0有哪些新功能值得我们体验呢?下面是UC浏览器电脑版3.0功能一览,我们一起来看看. 1.大图速览 在新版UC浏览器地址栏中,你会发现有一个图标是之前一直没有出现的,这就是正式版中新增加的"大图速览".具体来说就是当我们浏览微博或淘宝这样一些特殊网站时,鼠标悬停能够直接浏览到小图所对应的清晰大图,省却了之前必须点击才能查看的麻烦. 实测看也还不错,浏览器在大图尺寸及细节把握上比较得体,既不会对

微信1.1电脑版新功能有哪些

  电脑版微信苦苦的等待终于等来了1.1新版本,新东西更新是一个必走过程,TA到底更新了哪些新功能,新内容呢?小编一个个来告诉你这些新功能怎么用. 1.消息撤回 人称"毒舌"的我最大特点是说话[快!][狠!][准!],要是图一时之快说错话怎么办呢?右键需要撤回的消息选择[撤回]. 消息撤回成功会有消息提醒哦!就算能这样也不能随便说话Di~ 消息虽能撤回但并不是无敌的,因为发出去的消息只有两分钟的可撤回时间,超出120秒没有撤回你就等着朋友的批评吧~ 2.At他人,@群聊成员消息提醒 出

OS X Yosemite 10.10正式版新功能

  OS X Yosemite 10.10正式版新功能介绍在今天早上终于正式发布了,这是 OS X系统历史上变化最大的一次,OS X终于全面的走向了扁平化. 在这个时候我们自然是想要尽快的体验到正式版的乐趣,怎么办呢?方法一:打开你的 Mac App Store ,在首页的幻灯片里面就有 OS X 10.10 的下载地址,直接下载更新即可.方法二:在PC6苹果网下载 OS X 10.10 完整版固件然后再安装更新.然后再验证更新即可. S X Yosemite 安装应用中 InstallESD.

 QQ2012 Beta1(Q+)版新功能

QQ2012已经发布了Beta测试版,增加了多项新功能.随后,QQ2012 Beta1(Q+)也闪亮登场.新版本具备QQ2012 Beta1的所有功能,Q+也升级到3.2版本,上线多个酷炫新功能:Q+桌面新增我的网盘功能,提供方便的云服务:优化Q+桌面体验,使用更快捷:新增应用简介和详情,应用信息方便知:优化分屏切换体验,鼠标右键实现换屏等等. 点击下载QQ2012 Beta1(Q+)版 QQ2012 Beta1(Q+)版发布 QQ2012 Beta1(Q+)版新功能: 1.Q+桌面新增我的网盘