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)
{
/* get opt comment if we need chengang882@pingan.com.cn at 2016-08-23
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;
}


callsession新功能版的更多相关文章
- VS2015预览版中的C#6.0 新功能(二)
VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(三) 自动属性的增强 只读自动属性 以前自动属性必须同时提供setter和getter方法,因而只读属性只能通 ...
- VS2015预览版中的C#6.0 新功能(三)
VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(二) Using static 使用using StaticClass,你可以访问StaticClass类里的 ...
- VS2015预览版中的C#6.0 新功能(一)
VS2015预览版中的C#6.0 新功能(二) VS2015预览版中的C#6.0 新功能(三) VS2015的预览版在11月12日发布了,下面让我们来看看C#都提供了哪些新的功能. 字符串添写(Str ...
- WordPress版微信小程序3.1.5版的新功能
产品的完善是无止境,每过段时间就会发现产品的新问题,使用的人越多,提的需求也会越多,我听得最多的一句话就是:如果加上某某功能就完美了.其实,完美是不存在的,每个人的视角不一样,完美的定义也是不一样的. ...
- Android Studio 2.3 正式版新功能,你不来看看?!
2017.3.3 Google老大发布了Android Studio 2.3正式版. 在许多2.3beta版本的基础上修复了bug然后推出了正式版.提供了一些新特性,和对部分已有功能的修改完善. Bu ...
- Android O 正式版新功能
ref: Android O新特性和行为变更总结zzhttp://www.cnblogs.com/bluestorm/p/7148134.html Android O正式版带来了诸多新功能,如Tens ...
- 【转】odoo11新功能及绿色版汇总
昆山-Jeffery 11:34:00 ,odoo11 新功能: 评论:看到截图,感觉美工上又有所提高 官方的发布说明:https://www.odoo.com/nl_NL/page/odoo-11- ...
- Redis 6.0 正式版终于发布了!除了多线程还有什么新功能?
Redis 6.0.1 于 2020 年 5 月 2 日正式发布了,如 Redis 作者 antirez 所说,这是迄今为止最"企业"化的版本,也是有史以来改动最大的一个 Redi ...
- .NET 6 预览版 7:新功能已完成 ,将专注于改进
.NET 团队的项目经理 Richard Lander在宣布 .NET 6 Preview 7 时说:"这是 .NET 预览的又一季的结束.", 中文翻译:.NET 6 预览版 7 ...
随机推荐
- PHP实现发红包程序(helloweba网站经典小案例)
我们先来分析下规律. 设定总金额为10元,有N个人随机领取: N=1 第一个 则红包金额=X元: N=2 第二个 为保证第二个红包可以正常发出,第一个红包金额=0.01至9.99之间的某个随机数. 第 ...
- Hibernate动态更新
Hibernate一级缓存: Hibernate有一级和二级缓存.一级缓存就是Session. 在Hibernate启动的时候,SessionFactory解析映射文件的时候,会根据映射文件中的字段生 ...
- js获取页面url的方法
我们可以用javascript获得其中的各个部分 1, window.location.href 整个URl字符串(在浏览器中就是完整的地址栏) 本例返回值: http://ifisker.com/b ...
- virtualbox 不能为虚拟电脑打开一个新任务/VT-x features locked or unavailable in MSR.
确保了主机的BIOS中开启了Intel Virtual Technology,虚拟机配置中勾选了“启用VT-x/AMD-V”. 这是因为CPU不支持VT-X技术或者VT-X技术被锁定. 如果不打开虚拟 ...
- whereis命令
whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返回所有信息. 和find相比,whereis查找的速度非 ...
- Asp.net面试题
Asp.net核心技术思想 1.概述反射和序列化 反射:程序集包含模块,而模块包含类型,类型又包含成员.反射则提供了封装程序集.模块和类型的对象.您可以使用反射动态地创建类型的实例,将类型绑定到现有对 ...
- <转载>NPOI Excel 单元格背景颜色对照表
我转载地址:http://www.holdcode.com/web/details/117 NPOI Excel 单元格颜色对照表,在引用了 NPOI.dll 后可通过 ICellStyle 接口的 ...
- Unity中下载和本地保存实例
原地址:http://www.linuxidc.com/Linux/2011-10/45888.htm Download.cs using UnityEngine; using System.Coll ...
- ios5之后arc的问题
原创: 自从ios5以后, apple官方引进了ARC (automaically reference count 自动索引计数) 这个新特性, 简单的说就是对象设置为nil(空引用)之后, 当自动索 ...
- 对大一新生开始学习C语言课程谈几点看法
大家好,首先祝贺大家进入了大学,迈入了大学的校门,也意味着开始了新的征程,希望大家能够有一个美好的大学四年. 先做下自我介绍,我叫李帅阳,(大家可以称呼我 李老师,或是班助,或是...)这是在邹欣老师 ...