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 ...
随机推荐
- ECSHOP管理员密码忘记了怎么办?
ECSHOP管理员密码忘记了怎么办? ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2013-09-06 不小心在后台把管理员全部给清空了,闹的网站都无法登陆了?有 ...
- javascript学习随笔(二)原型prototype
JavaScript三类方法: 1.类方法:2.对象方法:3.原型方法;注意三者异同 例: function People(name){ this.name=name; //对象方法 this.Int ...
- mysql 服务无法启动 服务没有报告任何错误
问题 解决方法 1.必须保证 mysql 下不存在 data 文件夹,如果存在 data 文件夹,则先删除 mysql 下的 data 文件夹,然后初始化 mysqld --initialize 服务 ...
- SSL协议运行机制
SSL/TLS协议运行机制 一.作用 不使用SSL/TLS的HTTP通信,就是不加密的通信.所有信息明文传播,带来了三大风险. (1) 窃听风险(eavesdropping):第三方可以获知通信内容. ...
- Java JNI 编程进阶 实例+c++数据类型与jni数据类型转换
原文:http://www.iteye.com/topic/295776 JNI一直以来都很少去关注,但却是我心中的一个结,最近这几天刚好手头有点时间,因此抽空看了一下这方面的东西,整理了一份文档,J ...
- Java-Java中System.arraycopy() 和 Arrays.copyOf()两者之间的区别
如果我们想拷贝一个数组,我们可能会使用System.arraycopy()或者Arrays.copyof()两种方式.在这里,我们将使用一个比较简单的示例来阐述两者之间的区别. 1.示例代码: Sys ...
- Maven 安装以及一些开发技巧
解压 apache-maven-3.2.5 在conf ->sites中配置repository 的路径. Eclipse 配置 maven 2. 3. 一些小BUG 或开发技巧 eclipse ...
- SGU 170 Particles(规律题)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=170 解题报告:输入两个由'+'和'-'组成的字符串,让你判断第二个串能不能由第一个 ...
- Coursera台大机器学习课程笔记15 -- Three Learning Principles
这节课是最后一节,讲的是做机器学习的三个原则. 第一个是Occan's razor,即越简单越好.接着解释了什么是简单的hypothesis,什么是简单的model.关于为什么越简单越好,林老师从大致 ...
- hrb 2134 素数
分拆素数和 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 176(99 users) Total Accepted: 106(93 u ...