Front View plug-in does not init if no sensor added.
Fixing some format to make strings shorter.
Now trying to start SoundGraphAccess.exe process from same directory.
Packed mode now can display three sensors along with the current time.
1 #include "UserAccountControl.h"
4 #pragma comment (lib, "kernel32.lib")
5 #pragma comment (lib, "advapi32.lib")
8 #include <msclr\marshal.h>
9 #include <msclr\marshal_windows.h>
11 using namespace msclr::interop;
13 using namespace System::ComponentModel;
14 using namespace Microsoft::Win32;
16 namespace UacHelpers {
18 Process^ UserAccountControl::CreateProcessAsAdmin(System::String^ exePath, System::String^ arguments)
20 ProcessStartInfo^ psi = gcnew ProcessStartInfo(exePath, arguments);
21 psi->UseShellExecute = true;
23 return Process::Start(psi);
26 Process^ UserAccountControl::CreateProcessAsStandardUser(System::String^ exePath, System::String^ arguments)
28 marshal_context context;
30 //If the current process is not elevated, then there's no reason to go through the hassle --
31 //just use the standard System.Diagnostics.Process facilities.
32 if (!IsCurrentProcessElevated)
34 return Process::Start(exePath, arguments);
37 //The following implementation is roughly based on Aaron Margosis' post:
38 //http://blogs.msdn.com/aaron_margosis/archive/2009/06/06/faq-how-do-i-start-a-program-as-the-desktop-user-from-an-elevated-app.aspx
40 //Enable SeIncreaseQuotaPrivilege in this process. (This requires administrative privileges.)
41 HANDLE hProcessToken = NULL;
42 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hProcessToken))
44 throw gcnew Win32Exception(GetLastError());
49 tkp.PrivilegeCount = 1;
50 LookupPrivilegeValueW(NULL, SE_INCREASE_QUOTA_NAME, &tkp.Privileges[0].Luid);
51 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
52 AdjustTokenPrivileges(hProcessToken, FALSE, &tkp, 0, NULL, NULL);
53 DWORD dwLastErr = GetLastError();
54 CloseHandle(hProcessToken);
55 if (ERROR_SUCCESS != dwLastErr)
57 throw gcnew Win32Exception(dwLastErr);
61 //Get window handle representing the desktop shell. This might not work if there is no shell window, or when
62 //using a custom shell. Also note that we're assuming that the shell is not running elevated.
63 HWND hShellWnd = GetShellWindow();
64 if (hShellWnd == NULL)
66 throw gcnew System::InvalidOperationException("Unable to locate shell window; you might be using a custom shell");
69 //Get the ID of the desktop shell process.
71 GetWindowThreadProcessId(hShellWnd, &dwShellPID);
74 throw gcnew Win32Exception(GetLastError());
77 //Open the desktop shell process in order to get the process token.
78 HANDLE hShellProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwShellPID);
79 if (hShellProcess == NULL)
81 throw gcnew Win32Exception(GetLastError());
84 HANDLE hShellProcessToken = NULL;
85 HANDLE hPrimaryToken = NULL;
88 //Get the process token of the desktop shell.
89 if (!OpenProcessToken(hShellProcess, TOKEN_DUPLICATE, &hShellProcessToken))
91 throw gcnew Win32Exception(GetLastError());
94 //Duplicate the shell's process token to get a primary token.
95 const DWORD dwTokenRights = TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID;
96 if (!DuplicateTokenEx(hShellProcessToken, dwTokenRights, NULL, SecurityImpersonation, TokenPrimary, &hPrimaryToken))
98 throw gcnew Win32Exception(GetLastError());
101 //Start the target process with the new token.
102 STARTUPINFO si = {0}; si.cb = sizeof(si);
103 PROCESS_INFORMATION pi = {0};
104 if (!CreateProcessWithTokenW(hPrimaryToken, 0,
105 context.marshal_as<LPCWSTR>(exePath), context.marshal_as<LPWSTR>(exePath + " " + arguments),
106 0, NULL, NULL, &si, &pi))
108 throw gcnew Win32Exception(GetLastError());
110 CloseHandle(pi.hProcess);
111 CloseHandle(pi.hThread);
113 return Process::GetProcessById(pi.dwProcessId);
117 if (hShellProcessToken != NULL)
118 CloseHandle(hShellProcessToken);
120 if (hPrimaryToken != NULL)
121 CloseHandle(hPrimaryToken);
123 if (hShellProcess != NULL)
124 CloseHandle(hShellProcess);
128 bool UserAccountControl::IsUserAdmin::get()
130 if (UserAccountControl::IsUacEnabled)
131 return GetProcessTokenElevationType() != TokenElevationTypeDefault; //split token
133 //If UAC is off, we can't rely on the token; check for Admin group.
134 return WindowsPrincipal(WindowsIdentity::GetCurrent()).IsInRole("Administrators");
137 bool UserAccountControl::IsUacEnabled::get()
139 //Check the HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA registry value.
140 RegistryKey^ key = Registry::LocalMachine->OpenSubKey(UacRegistryKey, false);
141 return key->GetValue(UacRegistryValue)->Equals(1);
144 void UserAccountControl::DisableUac()
146 SetUacRegistryValue(false);
149 void UserAccountControl::DisableUacAndRestartWindows()
155 void UserAccountControl::EnableUac()
157 SetUacRegistryValue(true);
160 void UserAccountControl::EnableUacAndRestartWindows()
166 bool UserAccountControl::IsCurrentProcessElevated::get()
168 return GetProcessTokenElevationType() == TokenElevationTypeFull; //elevated
171 bool UserAccountControl::IsCurrentProcessVirtualized::get()
176 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
177 throw gcnew Win32Exception(GetLastError());
179 DWORD virtualizationEnabled;
181 if (!GetTokenInformation(hToken, TokenVirtualizationEnabled, &virtualizationEnabled, sizeof(virtualizationEnabled), &dwSize))
182 throw gcnew Win32Exception(GetLastError());
184 return virtualizationEnabled != 0;
192 int UserAccountControl::GetProcessTokenElevationType()
197 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
198 throw gcnew Win32Exception(GetLastError());
200 TOKEN_ELEVATION_TYPE elevationType;
202 if (!GetTokenInformation(hToken, TokenElevationType, &elevationType, sizeof(elevationType), &dwSize))
203 throw gcnew Win32Exception(GetLastError());
205 return elevationType;
213 void UserAccountControl::SetUacRegistryValue(bool enabled)
215 RegistryKey^ key = Registry::LocalMachine->OpenSubKey(UacRegistryKey, true);
216 key->SetValue(UacRegistryValue, enabled ? 1 : 0);
219 void UserAccountControl::RestartWindows()
221 InitiateSystemShutdownEx(NULL, NULL, 0/*Timeout*/,
222 TRUE/*ForceAppsClosed*/, TRUE/*RebootAfterShutdown*/,
223 SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG | SHTDN_REASON_FLAG_PLANNED);
224 //This shutdown flag corresponds to: "Operating System: Reconfiguration (Planned)".