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 ...
随机推荐
- ArrayList与LinkedList区别
ArrayList 采用的是数组形式来保存对象的,这种方式将对象放在连续的位置中,所以最大的缺点就是插入删除时非常麻烦LinkedList 采用的将对象存放在独立的空间中,而且在每个空间中还保存下一个 ...
- jsp页面显示数据库乱码
如何页面是utf-8,数据库也是的话,页面显示数据库乱码的话,就是数据库的格式有问题
- ssh事务配置
<!-- 配置业务层 --> <bean id="employeeService" class="cn.bdqn.jboa.service.impl.E ...
- 新浪微博客户端(5)-自定义UISearchBar
iOS自带的UISearchBar有很多限制,我们可以使用UITextField做出一个类似于SearchBar的效果. //===================================== ...
- Change ICON of MFC Application and Dialog
Change ICON of MFC Application and Dialoghttp://www.codeproject.com/Tips/406870/Change-ICON-of-MFC-A ...
- Gulp, 比Grunt更好用的前端构建工具
Gulp, 比Grunt更好用的前端构建工具 本文主要从两个方面介绍Gulp:一,Gulp相对于Grunt的优势: 二,Gulp的安装和使用流程 Gulp相对于Grunt的优势 gulp.js 的作者 ...
- 调用gluNurbsCurve绘制圆弧
<OpenGL编程指南>第12章第3小结专门介绍调用GLU绘制NURBS曲线或曲面,很可惜的是并未给出绘制圆弧的例子.网上可以找到很多绘制整个园的例子,却没圆弧例子,自己瞎折腾了2个礼拜, ...
- UIImageView 动画 / UIImage 方向
UIImage 方向 UIImage imageOrientation是相对当前屏幕的横竖屏来判断方向 如果本身是横屏, 照片也是横屏的话, 方向是正方向 BOOL b1 = (originalIma ...
- 白手起家搭建django app
$django-admin.py startproject web2 $cd web2/ $python manage.py startapp blog $vim web2/settings.py 注 ...
- nginx: [error] invalid PID number "" in "/usr/local/nginx/logs/nginx.pid"
iwangzheng.com tty:[0] jobs:[0] cwd:[/opt/nginx/conf] 12:45 [root@a02.cmsapi]$ /usr/local/nginx/sbin ...