1+ #include "uiaccess.h"
2+ #include <tlhelp32.h>
3+ #include <tchar.h>
4+
5+ static DWORD DuplicateWinloginToken (DWORD dwSessionId , DWORD dwDesiredAccess , PHANDLE phToken ) {
6+ DWORD dwErr ;
7+ PRIVILEGE_SET ps ;
8+
9+ ps .PrivilegeCount = 1 ;
10+ ps .Control = PRIVILEGE_SET_ALL_NECESSARY ;
11+
12+ if (LookupPrivilegeValue (NULL , SE_TCB_NAME , & ps .Privilege [0 ].Luid )) {
13+ HANDLE hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 );
14+ if (INVALID_HANDLE_VALUE != hSnapshot ) {
15+ BOOL bCont , bFound = FALSE;
16+ PROCESSENTRY32 pe ;
17+
18+ pe .dwSize = sizeof (pe );
19+ dwErr = ERROR_NOT_FOUND ;
20+
21+ for (bCont = Process32First (hSnapshot , & pe ); bCont ; bCont = Process32Next (hSnapshot , & pe )) {
22+ HANDLE hProcess ;
23+
24+ if (0 != _tcsicmp (pe .szExeFile , TEXT ("winlogon.exe" ))) {
25+ continue ;
26+ }
27+
28+ hProcess = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION , FALSE, pe .th32ProcessID );
29+ if (hProcess ) {
30+ HANDLE hToken ;
31+ DWORD dwRetLen , sid ;
32+
33+ if (OpenProcessToken (hProcess , TOKEN_QUERY | TOKEN_DUPLICATE , & hToken )) {
34+ BOOL fTcb ;
35+
36+ if (PrivilegeCheck (hToken , & ps , & fTcb ) && fTcb ) {
37+ if (GetTokenInformation (hToken , TokenSessionId , & sid , sizeof (sid ), & dwRetLen ) && sid == dwSessionId ) {
38+ bFound = TRUE;
39+ if (DuplicateTokenEx (hToken , dwDesiredAccess , NULL , SecurityImpersonation , TokenImpersonation , phToken )) {
40+ dwErr = ERROR_SUCCESS ;
41+ } else {
42+ dwErr = GetLastError ();
43+ }
44+ }
45+ }
46+ CloseHandle (hToken );
47+ }
48+ CloseHandle (hProcess );
49+ }
50+
51+ if (bFound ) break ;
52+ }
53+
54+ CloseHandle (hSnapshot );
55+ } else {
56+ dwErr = GetLastError ();
57+ }
58+ } else {
59+ dwErr = GetLastError ();
60+ }
61+
62+
63+ return dwErr ;
64+ }
65+
66+ static DWORD CreateUIAccessToken (PHANDLE phToken ) {
67+ DWORD dwErr ;
68+ HANDLE hTokenSelf ;
69+
70+ if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY | TOKEN_DUPLICATE , & hTokenSelf )) {
71+ DWORD dwSessionId , dwRetLen ;
72+
73+ if (GetTokenInformation (hTokenSelf , TokenSessionId , & dwSessionId , sizeof (dwSessionId ), & dwRetLen )) {
74+ HANDLE hTokenSystem ;
75+
76+ dwErr = DuplicateWinloginToken (dwSessionId , TOKEN_IMPERSONATE , & hTokenSystem );
77+ if (ERROR_SUCCESS == dwErr ) {
78+ if (SetThreadToken (NULL , hTokenSystem )) {
79+ if (DuplicateTokenEx (hTokenSelf , TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_DEFAULT , NULL , SecurityAnonymous , TokenPrimary , phToken )) {
80+ BOOL bUIAccess = TRUE;
81+
82+ if (!SetTokenInformation (* phToken , TokenUIAccess , & bUIAccess , sizeof (bUIAccess ))) {
83+ dwErr = GetLastError ();
84+ CloseHandle (* phToken );
85+ }
86+ } else {
87+ dwErr = GetLastError ();
88+ }
89+ RevertToSelf ();
90+ } else {
91+ dwErr = GetLastError ();
92+ }
93+ CloseHandle (hTokenSystem );
94+ }
95+ } else {
96+ dwErr = GetLastError ();
97+ }
98+
99+ CloseHandle (hTokenSelf );
100+ } else {
101+ dwErr = GetLastError ();
102+ }
103+
104+ return dwErr ;
105+ }
106+
107+ static BOOL CheckForUIAccess (DWORD * pdwErr , DWORD * pfUIAccess ) {
108+ BOOL result = FALSE;
109+ HANDLE hToken ;
110+
111+ if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY , & hToken )) {
112+ DWORD dwRetLen ;
113+
114+ if (GetTokenInformation (hToken , TokenUIAccess , pfUIAccess , sizeof (* pfUIAccess ), & dwRetLen )) {
115+ result = TRUE;
116+ } else {
117+ * pdwErr = GetLastError ();
118+ }
119+ CloseHandle (hToken );
120+ } else {
121+ * pdwErr = GetLastError ();
122+ }
123+
124+ return result ;
125+ }
126+
127+ DWORD PrepareForUIAccess () {
128+ DWORD dwErr ;
129+ HANDLE hTokenUIAccess ;
130+ BOOL fUIAccess ;
131+
132+ if (CheckForUIAccess (& dwErr , & fUIAccess )) {
133+ if (fUIAccess ) {
134+ dwErr = ERROR_SUCCESS ;
135+ } else {
136+ dwErr = CreateUIAccessToken (& hTokenUIAccess );
137+ if (ERROR_SUCCESS == dwErr ) {
138+ STARTUPINFO si ;
139+ PROCESS_INFORMATION pi ;
140+
141+ GetStartupInfo (& si );
142+ if (CreateProcessAsUser (hTokenUIAccess , NULL , GetCommandLine (), NULL , NULL , FALSE, 0 , NULL , NULL , & si , & pi )) {
143+ CloseHandle (pi .hProcess ), CloseHandle (pi .hThread );
144+ ExitProcess (0 );
145+ } else {
146+ dwErr = GetLastError ();
147+ }
148+
149+ CloseHandle (hTokenUIAccess );
150+ }
151+ }
152+ }
153+
154+ return dwErr ;
155+ }
0 commit comments