Click here to Skip to main content
15,884,176 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi everyone,
now i wrote a windows service program, and it's ok in windows operation system except windows8, in this service, when i plug-in a usb device, this service check the device and open another execute program to communicate with this device.
Now, in win8, the service can not open the exe application, CreateProcessAsUser return error code 740.
and if you remove the UAC feature of the exe app, it's ok in win8. so i guess the problem belongs the previlege of UAC or windows8 right control?

2. if i load the token with "explorer.exe", the service run the exe app with current user account, if changed to "winlogon.exe", it runs by SYSTEM previlege, we can check these info in task manager. But i must run exe with current user in windows8.

please help me, my friends, it confused me very long time.GOD. Who can give me some ideas????

the codes as belows:



BOOL LaunchAppIntoDifferentSession(LPCTSTR szAppFullPath)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL bResult = FALSE;
DWORD dwSessionId,winlogonPid;
HANDLE hUserToken,hUserTokenDup,hPToken,hProcess;
DWORD dwCreationFlags;

// Log the client on to the local computer.

dwSessionId = WTSGetActiveConsoleSessionId(); //得到当前用户的会话ID

//////////////////////////////////////////
// Find the winlogon process
////////////////////////////////////////

PROCESSENTRY32 procEntry; //用来存放快照进程信息的一个结构体
//函数为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程[THREAD])建立一个快照[snapshot]
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}

procEntry.dwSize = sizeof(PROCESSENTRY32);

if (!Process32First(hSnap, &procEntry)) //获得第一个进程的句柄.
{
return FALSE;
}

do
{
if (_wcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0) //查找winlogon.exe
{
// We found a winlogon process...make sure it's running in the console session
DWORD winlogonSessId = 0;
if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId)//得到与进程ID对应的终端服务会话ID
{
winlogonPid = procEntry.th32ProcessID;
break;
}
}

} while (Process32Next(hSnap, &procEntry)); //获得下一个进程的句柄

////////////////////////////////////////////////////////////////////////

WTSQueryUserToken(dwSessionId,&hUserToken); //通过会话ID得到令牌
dwCreationFlags = NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE;
//指定新进程的主窗口特性
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
//用于标识启动应用程序所在的桌面的名字。如果该桌面存在,
//新进程便与指定的桌面相关联。   如果桌面不存在,
//便创建一个带有默认属性的桌面,并使用为新进程指定的名字。   
//如果lpDesktop是NULL(这是最常见的情况),那么该进程将与当前桌面相关联
si.lpDesktop = _T("winsta0\\default");
ZeroMemory(&pi, sizeof(pi));
/*
TOKEN_PRIVILEGES Structure 的示意图
---------------------------------------------------------
| PrivilegeCount |
---------------------------------------------------------
| Luid | Luid | Luid | …… |
| | | | |
| Attributes | Attributes | Attributes | …… |
| | | | |
---------------------------------------------------------
Privileges[0] Privileges[1] Privileges[2] ……

*/
TOKEN_PRIVILEGES tp;
LUID luid;
hProcess = OpenProcess(MAXIMUM_ALLOWED,FALSE,winlogonPid); //获得进程句柄

if(!::OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY
|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_ADJUST_SESSIONID
|TOKEN_READ|TOKEN_WRITE,&hPToken)) //获得令牌句柄
{
int abcd = GetLastError();
printf("Process token open Error: %u\n",GetLastError());
}

if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid))
{
printf("Lookup Privilege value Error: %u\n",GetLastError());
}
tp.PrivilegeCount =1;
tp.Privileges[0].Luid =luid;
tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;

DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hUserTokenDup);//创建模拟令牌
int dup = GetLastError();
//change Token session id
//Adjust Token privilege
SetTokenInformation(hUserTokenDup,TokenSessionId,(void*)dwSessionId,sizeof(DWORD));

if (!AdjustTokenPrivileges(hUserTokenDup,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,NULL)) //这个函数启用或禁止 指定访问令牌的特权
{
int abc =GetLastError();
printf("Adjust Privilege value Error: %u\n",GetLastError());
}

if (GetLastError()== ERROR_NOT_ALL_ASSIGNED)
{
printf("Token does not have the provilege\n");
}

LPVOID pEnv =NULL;

if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE))
{
dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
}
else
pEnv=NULL;

// Launch the process in the client's logon session.

bResult = CreateProcessAsUser(
hUserTokenDup, // client's access token
szAppFullPath, // file to execute
NULL, // command line
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
dwCreationFlags, // creation flags
pEnv, // pointer to new environment block
NULL, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
);
// End impersonation of client.
//GetLastError Shud be 0

int iResultOfCreateProcessAsUser = GetLastError();

//Perform All the Close Handles task

CloseHandle(hProcess);
CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);
CloseHandle(hPToken);

return TRUE;
}
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900