V
VisualEleven
Guest
Environment: Win8.1 x64 VS2008SP1
In the Terminal Services(interactive), I launch a Dialog app(MFC Dialog Project, i.e named Test.exe),
// Call code in services program :
CCommon::LaunchApplication(TEXT("Test.exe"), TEXT(" -w 11 -h 11"));
// In my Dialog program, In CDialog::OnInitDialog() :
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
The Quest: The dialog app can be launched, the dialog window can be show very well in desktop, but the dialog window can not set to "HWND_TOPMOST", why?
If i run Test.exe directly, not call in services, the window can be top most.
Use the following code:
BOOL CCommon::GetCurrentActivateSessionId(DWORD& dwSessionId)
{
BOOL bRet = FALSE;
do
{
DWORD dwCount = 0;
PWTS_SESSION_INFO pSessionInfo = NULL;
if(!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount))
{
break;
}
for(DWORD i = 0; i != dwCount; ++i)
{
if(WTSActive == pSessionInfo.State)
{
dwSessionId = pSessionInfo.SessionId;
// Completed
bRet = TRUE;
break;
}
}
if(NULL != pSessionInfo) { WTSFreeMemory(pSessionInfo); pSessionInfo = NULL; }
if(!bRet)
{
DWORD dwSessionId = (DWORD)-1;
if(0xFFFFFFFF == (dwSessionId = WTSGetActiveConsoleSessionId()))
{
break;
}
// Completed
dwSessionId = dwSessionId;
bRet = TRUE;
}
} while (FALSE);
return bRet;
}
BOOL CCommon::GetCurrentActivateDesktop(LPTSTR lpszDesktop, int nLength)
{
BOOL bRet = FALSE;
HDESK hDesktop = NULL;
do
{
if(NULL == (hDesktop = OpenInputDesktop(0, FALSE, GENERIC_ALL)))
{
break;
}
if(!GetUserObjectInformation(hDesktop, UOI_NAME, lpszDesktop, nLength, NULL))
{
break;
}
bRet = TRUE;
} while (FALSE);
if(NULL != hDesktop) { CloseDesktop(hDesktop); hDesktop = NULL; }
return bRet;
}
HANDLE CCommon::GetCurrentActivateUserToken(HANDLE hProcess, DWORD dwSessionId)
{
HANDLE hTokenDup = NULL;
HANDLE hToken = NULL;
do
{
// Open process token
if(!OpenProcessToken(hProcess,
TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY |
TOKEN_DUPLICATE |
TOKEN_ASSIGN_PRIMARY |
TOKEN_ADJUST_SESSIONID |
TOKEN_READ |
TOKEN_WRITE,
&hToken))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Open Process Token Failed!"));
break;
}
// Lookup privileges
LUID luid = {0};
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Lookup Privilege Value Failed!"));
break;
}
TOKEN_PRIVILEGES tp = {0};
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Duplicate token
if(!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Duplicate Token Failed!"));
break;
}
// Set token information
if(!SetTokenInformation(hTokenDup, TokenSessionId, (void*)&dwSessionId, sizeof(dwSessionId)))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Set Token Information Failed!"));
break;
}
// Adjust privilege
if(!AdjustTokenPrivileges(hTokenDup, FALSE, &tp, sizeof(tp), NULL, NULL))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Adjust Token Privilege Failed!"));
break;
}
// Completed
} while (FALSE);
if(NULL != hToken) { CloseHandle(hToken); hToken = NULL; }
return hTokenDup;
}
BOOL CCommon::LaunchApplication(LPCTSTR lpszExecute, LPCTSTR lpszCmdLine)
{
_ASSERT(NULL != lpszExecute);
_ASSERT(NULL != lpszCmdLine);
BOOL bRet = FALSE;
HANDLE hToken = NULL;
DWORD dwSessionId = (DWORD)-1;
LPVOID lpEnv = NULL;
do
{
// Get current activate session id
if(!GetCurrentActivateSessionId(dwSessionId))
{
PRINT(DBG_ERR, TEXT("CCommon::LaunchApplication() Get Current Activate Session Id Failed!"));
break;
}
// Get current activate user token
if(NULL == (hToken = GetCurrentActivateUserToken(GetCurrentProcess(), dwSessionId)))
{
PRINT(DBG_ERR, TEXT("CCommon::LaunchApplication() Get Current Activate User Token Failed!"));
break;
}
// Create process environment block
if(!CreateEnvironmentBlock(&lpEnv, hToken, FALSE))
{
PRINT(DBG_ERR, TEXT("CCommon::LaunchApplication() Create Environment Block Failed!"));
break;
}
// Default desktop
TCHAR szDesktop[MAX_PATH] = TEXT("Winsta0\\Default");
GetCurrentActivateDesktop(szDesktop, _countof(szDesktop));
// Get command line parameter
TCHAR szCmdLine[MAX_PATH] = {0};
if(NULL != lpszCmdLine) { StringCchPrintf(szCmdLine, _countof(szCmdLine), TEXT("%s"), lpszCmdLine); }
// Get execute file path
TCHAR szExecute[MAX_PATH] = {0};
GetModuleFileName(NULL, szExecute, _countof(szExecute));
_tcsrchr(szExecute, TEXT(\\))[1] = TEXT(\0);
StringCbCat(szExecute, _countof(szExecute) - _tcslen(szExecute), lpszExecute);
// Launch process
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
si.lpDesktop = szDesktop;
if(!CreateProcessAsUser(hToken,
szExecute,
szCmdLine,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
lpEnv,
NULL,
&si,
&pi))
{
PRINT(DBG_ERR, TEXT("CCommon::LaunchApplication() Create Process Failed!"));
break;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
// Completed
bRet = TRUE;
} while (FALSE);
if(NULL != lpEnv) { DestroyEnvironmentBlock(lpEnv); lpEnv = NULL; }
if(NULL != hToken) { CloseHandle(hToken); hToken = NULL; }
return bRet;
}
Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
Continue reading...
In the Terminal Services(interactive), I launch a Dialog app(MFC Dialog Project, i.e named Test.exe),
// Call code in services program :
CCommon::LaunchApplication(TEXT("Test.exe"), TEXT(" -w 11 -h 11"));
// In my Dialog program, In CDialog::OnInitDialog() :
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
The Quest: The dialog app can be launched, the dialog window can be show very well in desktop, but the dialog window can not set to "HWND_TOPMOST", why?
If i run Test.exe directly, not call in services, the window can be top most.
Use the following code:
BOOL CCommon::GetCurrentActivateSessionId(DWORD& dwSessionId)
{
BOOL bRet = FALSE;
do
{
DWORD dwCount = 0;
PWTS_SESSION_INFO pSessionInfo = NULL;
if(!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount))
{
break;
}
for(DWORD i = 0; i != dwCount; ++i)
{
if(WTSActive == pSessionInfo.State)
{
dwSessionId = pSessionInfo.SessionId;
// Completed
bRet = TRUE;
break;
}
}
if(NULL != pSessionInfo) { WTSFreeMemory(pSessionInfo); pSessionInfo = NULL; }
if(!bRet)
{
DWORD dwSessionId = (DWORD)-1;
if(0xFFFFFFFF == (dwSessionId = WTSGetActiveConsoleSessionId()))
{
break;
}
// Completed
dwSessionId = dwSessionId;
bRet = TRUE;
}
} while (FALSE);
return bRet;
}
BOOL CCommon::GetCurrentActivateDesktop(LPTSTR lpszDesktop, int nLength)
{
BOOL bRet = FALSE;
HDESK hDesktop = NULL;
do
{
if(NULL == (hDesktop = OpenInputDesktop(0, FALSE, GENERIC_ALL)))
{
break;
}
if(!GetUserObjectInformation(hDesktop, UOI_NAME, lpszDesktop, nLength, NULL))
{
break;
}
bRet = TRUE;
} while (FALSE);
if(NULL != hDesktop) { CloseDesktop(hDesktop); hDesktop = NULL; }
return bRet;
}
HANDLE CCommon::GetCurrentActivateUserToken(HANDLE hProcess, DWORD dwSessionId)
{
HANDLE hTokenDup = NULL;
HANDLE hToken = NULL;
do
{
// Open process token
if(!OpenProcessToken(hProcess,
TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY |
TOKEN_DUPLICATE |
TOKEN_ASSIGN_PRIMARY |
TOKEN_ADJUST_SESSIONID |
TOKEN_READ |
TOKEN_WRITE,
&hToken))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Open Process Token Failed!"));
break;
}
// Lookup privileges
LUID luid = {0};
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Lookup Privilege Value Failed!"));
break;
}
TOKEN_PRIVILEGES tp = {0};
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Duplicate token
if(!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Duplicate Token Failed!"));
break;
}
// Set token information
if(!SetTokenInformation(hTokenDup, TokenSessionId, (void*)&dwSessionId, sizeof(dwSessionId)))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Set Token Information Failed!"));
break;
}
// Adjust privilege
if(!AdjustTokenPrivileges(hTokenDup, FALSE, &tp, sizeof(tp), NULL, NULL))
{
PRINT(DBG_ERR, TEXT("CCommon::GetCurrentActivateUserToken() Adjust Token Privilege Failed!"));
break;
}
// Completed
} while (FALSE);
if(NULL != hToken) { CloseHandle(hToken); hToken = NULL; }
return hTokenDup;
}
BOOL CCommon::LaunchApplication(LPCTSTR lpszExecute, LPCTSTR lpszCmdLine)
{
_ASSERT(NULL != lpszExecute);
_ASSERT(NULL != lpszCmdLine);
BOOL bRet = FALSE;
HANDLE hToken = NULL;
DWORD dwSessionId = (DWORD)-1;
LPVOID lpEnv = NULL;
do
{
// Get current activate session id
if(!GetCurrentActivateSessionId(dwSessionId))
{
PRINT(DBG_ERR, TEXT("CCommon::LaunchApplication() Get Current Activate Session Id Failed!"));
break;
}
// Get current activate user token
if(NULL == (hToken = GetCurrentActivateUserToken(GetCurrentProcess(), dwSessionId)))
{
PRINT(DBG_ERR, TEXT("CCommon::LaunchApplication() Get Current Activate User Token Failed!"));
break;
}
// Create process environment block
if(!CreateEnvironmentBlock(&lpEnv, hToken, FALSE))
{
PRINT(DBG_ERR, TEXT("CCommon::LaunchApplication() Create Environment Block Failed!"));
break;
}
// Default desktop
TCHAR szDesktop[MAX_PATH] = TEXT("Winsta0\\Default");
GetCurrentActivateDesktop(szDesktop, _countof(szDesktop));
// Get command line parameter
TCHAR szCmdLine[MAX_PATH] = {0};
if(NULL != lpszCmdLine) { StringCchPrintf(szCmdLine, _countof(szCmdLine), TEXT("%s"), lpszCmdLine); }
// Get execute file path
TCHAR szExecute[MAX_PATH] = {0};
GetModuleFileName(NULL, szExecute, _countof(szExecute));
_tcsrchr(szExecute, TEXT(\\))[1] = TEXT(\0);
StringCbCat(szExecute, _countof(szExecute) - _tcslen(szExecute), lpszExecute);
// Launch process
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
si.lpDesktop = szDesktop;
if(!CreateProcessAsUser(hToken,
szExecute,
szCmdLine,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
lpEnv,
NULL,
&si,
&pi))
{
PRINT(DBG_ERR, TEXT("CCommon::LaunchApplication() Create Process Failed!"));
break;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
// Completed
bRet = TRUE;
} while (FALSE);
if(NULL != lpEnv) { DestroyEnvironmentBlock(lpEnv); lpEnv = NULL; }
if(NULL != hToken) { CloseHandle(hToken); hToken = NULL; }
return bRet;
}
Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
Continue reading...