callsession新功能版

简介: 可以getopt解析参数。 也实现了将参数用空格分隔,来传给进程。 注意string和LPSTR数据类型的转换方法: LPSTR(lpCmdLine.c_str())   #include #include #include #include #include #i...

可以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;
}

  

 

目录
相关文章
|
9月前
|
Web App开发 缓存 API
回顾2022:Web性能方面有哪些新功能
回顾2022:Web性能方面有哪些新功能
55 0
|
7月前
|
前端开发 数据库 开发者
【RaETable】🚀🚀🚀一些新功能让你的开发更流畅
【RaETable】🚀🚀🚀一些新功能让你的开发更流畅
|
9月前
|
XML JSON JavaScript
版本升级 | v1.0.13发布,传下去:更好用了
本次更新主要聚焦兼容性的提升及结果报告格式的增加,另外对部分解析逻辑及使用体验进行了优化。特别鸣谢@Hugo-X的PR贡献~
95 0
版本升级 | v1.0.13发布,传下去:更好用了
|
搜索推荐 图形学
CorelDRAW2023更新了哪些新功能?
还更新了CorelDRAW Graphics Suite 2023引入了一项新工具、超过200款设计模板,以及最新的潘通颜色等等。CorelDRAW 全称“CorelDRAW Graphics Suite“,也就是众所周知的”CDR“,是一款智能高效的平面设计软件,广泛应用于排版印刷、矢量图形编辑及网页设计等领域,
223 0
|
搜索推荐
Boom3D软件2023最新版本有哪些新功能特色?
为了更好地感受音乐的魅力,Boom 3D 可以让你对音效进行个性化增强,并集成 3D 环绕立体声效果,可以让你在使用任何耳机时,都拥有纯正、优质的音乐体验。Boom 3D是一款充满神奇魅力的3D环绕音效升级版,BOOM 3D是一个全新的专业音频应用程序,提供丰富和强烈的音频与3D环绕声音,让耳机的声音更好!文件大小为40.65 MB,适用系统为WinXP/Win7/Win10/Win All,以下为介绍或使用方法。
282 0
Studio One2023软件最新版本有哪些新功能?
Studio One2023是一款全新实用的数字音乐制作软件,今天给大家带来的是Studio One中文版。这款软件功能非常的强大,能够帮助用户们快速的完成各种音频处理功能。能够记录、生产、混合、掌握和执行所有操作。从工作室到舞台,该软件以易用为核心,是您的创意合作伙伴。
247 0
|
计算机视觉
2023CorelDRAW什么时候更新?有哪些新功能
CorelDRAW是矢量软件中的最老牌大哥,功能强大没说的,此外它还集成了Corel PHOTO-PAINT、Corel Font Manager等在内的7个软件包。而且对比于illustrator和freehand,CorelDRAW更为简单易上手!
240 0
|
人工智能
Adobe2023升级版发布更新功能介绍
Adobe 2023全家桶已发布。Adobe 2022还没保存的。可以抓紧保存最后一波了。今天给大家带来了。Adobe 2023最新稳定版。WIN系统+MAC系统+M1系统。
291 0
|
机器学习/深度学习 自然语言处理 并行计算
全面支持 PyTorch 2.0:BladeDISC 5月~11月新功能发布
BladeDISC 上一次更新主要发布了 GPU AStitch 优化,方法来源于我们发表在 ASPLOS 2022上的论文AStitch。这一次,我们发布了 0.3.0 版本。
|
缓存 安全 芯片
CleanMyMac X2023版本有哪些新功能?
先回答另外一个问题:为什么要对 Mac 电脑进行清理?当然是空间不够用啊。对于新近几年的 Mac 电脑,扩容又不像以前换一块硬盘就好,还好事去问了一圈,对于 2016 年以后的 Mac 电脑的扩容建议是:外接一块移动硬盘。
101 0