Skip to content

Commit ce4e5f4

Browse files
committed
Add option to always start as administrator [Feature Request] winsiderss#546
1 parent 25c003b commit ce4e5f4

File tree

5 files changed

+446
-3
lines changed

5 files changed

+446
-3
lines changed

ProcessHacker/appsup.c

Lines changed: 343 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,3 +2148,346 @@ HBITMAP PhGetShieldBitmap(
21482148
return shieldBitmap;
21492149
}
21502150

2151+
// HACK - nightly build feature testing (dmex)
2152+
// TODO - move definitions to proper locations.
2153+
#include <taskschd.h>
2154+
DEFINE_GUID(CLSID_TaskScheduler, 0x0f87369f, 0xa4e5, 0x4cfc, 0xbd, 0x3e, 0x73, 0xe6, 0x15, 0x45, 0x72, 0xdd);
2155+
DEFINE_GUID(IID_ITaskService, 0x2FABA4C7, 0x4DA9, 0x4013, 0x96, 0x97, 0x20, 0xCC, 0x3F, 0xD4, 0x0F, 0x85);
2156+
DEFINE_GUID(IID_ITaskSettings2, 0x2C05C3F0, 0x6EED, 0x4C05, 0xA1, 0x5F, 0xED, 0x7D, 0x7A, 0x98, 0xA3, 0x69);
2157+
DEFINE_GUID(IID_ILogonTrigger, 0x72DADE38, 0xFAE4, 0x4b3e, 0xBA, 0xF4, 0x5D, 0x00, 0x9A, 0xF0, 0x2B, 0x1C);
2158+
DEFINE_GUID(IID_IExecAction, 0x4C3D624D, 0xfd6b, 0x49A3, 0xB9, 0xB7, 0x09, 0xCB, 0x3C, 0xD3, 0xF0, 0x47);
2159+
2160+
HRESULT PhRunAsAdminTask(
2161+
_In_ PWSTR TaskName
2162+
)
2163+
{
2164+
HRESULT status = S_FALSE;
2165+
VARIANT empty = { VT_EMPTY };
2166+
ITaskService* taskService = NULL;
2167+
ITaskFolder* taskFolder = NULL;
2168+
IRegisteredTask* taskRegisteredTask = NULL;
2169+
IRunningTask* taskRunningTask = NULL;
2170+
2171+
status = CoCreateInstance(
2172+
&CLSID_TaskScheduler,
2173+
NULL,
2174+
CLSCTX_INPROC_SERVER,
2175+
&IID_ITaskService,
2176+
&taskService
2177+
);
2178+
2179+
if (FAILED(status))
2180+
goto CleanupExit;
2181+
2182+
status = ITaskService_Connect(
2183+
taskService,
2184+
empty,
2185+
empty,
2186+
empty,
2187+
empty
2188+
);
2189+
2190+
if (FAILED(status))
2191+
goto CleanupExit;
2192+
2193+
status = ITaskService_GetFolder(
2194+
taskService,
2195+
L"\\",
2196+
&taskFolder
2197+
);
2198+
2199+
if (FAILED(status))
2200+
goto CleanupExit;
2201+
2202+
status = ITaskFolder_GetTask(
2203+
taskFolder,
2204+
TaskName,
2205+
&taskRegisteredTask
2206+
);
2207+
2208+
if (FAILED(status))
2209+
goto CleanupExit;
2210+
2211+
status = IRegisteredTask_RunEx(
2212+
taskRegisteredTask,
2213+
empty,
2214+
TASK_RUN_AS_SELF,
2215+
0,
2216+
NULL,
2217+
&taskRunningTask
2218+
);
2219+
2220+
CleanupExit:
2221+
2222+
if (taskRunningTask)
2223+
IRunningTask_Release(taskRunningTask);
2224+
if (taskRegisteredTask)
2225+
IRegisteredTask_Release(taskRegisteredTask);
2226+
if (taskFolder)
2227+
ITaskFolder_Release(taskFolder);
2228+
if (taskService)
2229+
ITaskService_Release(taskService);
2230+
2231+
return status;
2232+
}
2233+
2234+
HRESULT PhDeleteAdminTask(
2235+
_In_ PWSTR TaskName
2236+
)
2237+
{
2238+
HRESULT status = S_FALSE;
2239+
VARIANT empty = { VT_EMPTY };
2240+
ITaskService* taskService = NULL;
2241+
ITaskFolder* taskFolder = NULL;
2242+
2243+
status = CoCreateInstance(
2244+
&CLSID_TaskScheduler,
2245+
NULL,
2246+
CLSCTX_INPROC_SERVER,
2247+
&IID_ITaskService,
2248+
&taskService
2249+
);
2250+
2251+
if (FAILED(status))
2252+
goto CleanupExit;
2253+
2254+
status = ITaskService_Connect(
2255+
taskService,
2256+
empty,
2257+
empty,
2258+
empty,
2259+
empty
2260+
);
2261+
2262+
if (FAILED(status))
2263+
goto CleanupExit;
2264+
2265+
status = ITaskService_GetFolder(
2266+
taskService,
2267+
L"\\",
2268+
&taskFolder
2269+
);
2270+
2271+
if (FAILED(status))
2272+
goto CleanupExit;
2273+
2274+
status = ITaskFolder_DeleteTask(
2275+
taskFolder,
2276+
TaskName,
2277+
0
2278+
);
2279+
2280+
CleanupExit:
2281+
2282+
if (taskFolder)
2283+
ITaskFolder_Release(taskFolder);
2284+
if (taskService)
2285+
ITaskService_Release(taskService);
2286+
2287+
return status;
2288+
}
2289+
2290+
HRESULT PhCreateAdminTask(
2291+
_In_ PWSTR TaskName,
2292+
_In_ PWSTR FileName
2293+
)
2294+
{
2295+
HRESULT status = S_FALSE;
2296+
VARIANT empty = { VT_EMPTY };
2297+
ITaskService* taskService = NULL;
2298+
ITaskFolder* taskFolder = NULL;
2299+
ITaskDefinition* taskDefinition = NULL;
2300+
ITaskSettings* taskSettings = NULL;
2301+
ITaskSettings2* taskSettings2 = NULL;
2302+
ITriggerCollection* taskTriggerCollection = NULL;
2303+
ITrigger* taskTrigger = NULL;
2304+
ILogonTrigger* taskLogonTrigger = NULL;
2305+
IRegisteredTask* taskRegisteredTask = NULL;
2306+
IPrincipal* taskPrincipal = NULL;
2307+
IActionCollection* taskActionCollection = NULL;
2308+
IAction* taskAction = NULL;
2309+
IExecAction* taskExecAction = NULL;
2310+
2311+
status = CoCreateInstance(
2312+
&CLSID_TaskScheduler,
2313+
NULL,
2314+
CLSCTX_INPROC_SERVER,
2315+
&IID_ITaskService,
2316+
&taskService
2317+
);
2318+
2319+
if (FAILED(status))
2320+
goto CleanupExit;
2321+
2322+
status = ITaskService_Connect(
2323+
taskService,
2324+
empty,
2325+
empty,
2326+
empty,
2327+
empty
2328+
);
2329+
2330+
if (FAILED(status))
2331+
goto CleanupExit;
2332+
2333+
status = ITaskService_GetFolder(
2334+
taskService,
2335+
L"\\",
2336+
&taskFolder
2337+
);
2338+
2339+
if (FAILED(status))
2340+
goto CleanupExit;
2341+
2342+
status = ITaskService_NewTask(
2343+
taskService,
2344+
0,
2345+
&taskDefinition
2346+
);
2347+
2348+
if (FAILED(status))
2349+
goto CleanupExit;
2350+
2351+
status = ITaskDefinition_get_Settings(
2352+
taskDefinition,
2353+
&taskSettings
2354+
);
2355+
2356+
if (FAILED(status))
2357+
goto CleanupExit;
2358+
2359+
ITaskSettings_put_Compatibility(taskSettings, TASK_COMPATIBILITY_V2_1);
2360+
ITaskSettings_put_StartWhenAvailable(taskSettings, VARIANT_TRUE);
2361+
ITaskSettings_put_DisallowStartIfOnBatteries(taskSettings, VARIANT_FALSE);
2362+
ITaskSettings_put_StopIfGoingOnBatteries(taskSettings, VARIANT_FALSE);
2363+
ITaskSettings_put_ExecutionTimeLimit(taskSettings, L"PT0S");
2364+
//ITaskSettings_put_Priority(taskSettings, 1);
2365+
2366+
if (SUCCEEDED(ITaskSettings_QueryInterface(
2367+
taskSettings,
2368+
&IID_ITaskSettings2,
2369+
&taskSettings2
2370+
)))
2371+
{
2372+
ITaskSettings2_put_UseUnifiedSchedulingEngine(taskSettings2, VARIANT_TRUE);
2373+
ITaskSettings2_put_DisallowStartOnRemoteAppSession(taskSettings2, VARIANT_TRUE);
2374+
ITaskSettings2_Release(taskSettings2);
2375+
}
2376+
2377+
//status = ITaskDefinition_get_Triggers(
2378+
// taskDefinition,
2379+
// &taskTriggerCollection
2380+
// );
2381+
//
2382+
//if (FAILED(status))
2383+
// goto CleanupExit;
2384+
//
2385+
//status = ITriggerCollection_Create(
2386+
// taskTriggerCollection,
2387+
// TASK_TRIGGER_LOGON,
2388+
// &taskTrigger
2389+
// );
2390+
//
2391+
//if (FAILED(status))
2392+
// goto CleanupExit;
2393+
//
2394+
//status = ITrigger_QueryInterface(
2395+
// taskTrigger,
2396+
// &IID_ILogonTrigger,
2397+
// &taskLogonTrigger
2398+
// );
2399+
//
2400+
//if (FAILED(status))
2401+
// goto CleanupExit;
2402+
//
2403+
//ILogonTrigger_put_Id(taskLogonTrigger, L"LogonTriggerId");
2404+
//ILogonTrigger_put_UserId(taskLogonTrigger, PhGetString(PhGetTokenUserString(PhGetOwnTokenAttributes().TokenHandle, TRUE)));
2405+
2406+
status = ITaskDefinition_get_Principal(
2407+
taskDefinition,
2408+
&taskPrincipal
2409+
);
2410+
2411+
if (FAILED(status))
2412+
goto CleanupExit;
2413+
2414+
IPrincipal_put_RunLevel(taskPrincipal, TASK_RUNLEVEL_HIGHEST);
2415+
IPrincipal_put_LogonType(taskPrincipal, TASK_LOGON_INTERACTIVE_TOKEN);
2416+
2417+
status = ITaskDefinition_get_Actions(
2418+
taskDefinition,
2419+
&taskActionCollection
2420+
);
2421+
2422+
if (FAILED(status))
2423+
goto CleanupExit;
2424+
2425+
status = IActionCollection_Create(
2426+
taskActionCollection,
2427+
TASK_ACTION_EXEC,
2428+
&taskAction
2429+
);
2430+
2431+
if (FAILED(status))
2432+
goto CleanupExit;
2433+
2434+
status = IAction_QueryInterface(
2435+
taskAction,
2436+
&IID_IExecAction,
2437+
&taskExecAction
2438+
);
2439+
2440+
if (FAILED(status))
2441+
goto CleanupExit;
2442+
2443+
status = IExecAction_put_Path(
2444+
taskExecAction,
2445+
FileName
2446+
);
2447+
2448+
if (FAILED(status))
2449+
goto CleanupExit;
2450+
2451+
ITaskFolder_DeleteTask(
2452+
taskFolder,
2453+
TaskName,
2454+
0
2455+
);
2456+
2457+
status = ITaskFolder_RegisterTaskDefinition(
2458+
taskFolder,
2459+
TaskName,
2460+
taskDefinition,
2461+
TASK_CREATE_OR_UPDATE,
2462+
empty,
2463+
empty,
2464+
TASK_LOGON_INTERACTIVE_TOKEN,
2465+
empty,
2466+
&taskRegisteredTask
2467+
);
2468+
2469+
CleanupExit:
2470+
2471+
if (taskRegisteredTask)
2472+
IRegisteredTask_Release(taskRegisteredTask);
2473+
if (taskActionCollection)
2474+
IActionCollection_Release(taskActionCollection);
2475+
if (taskPrincipal)
2476+
IPrincipal_Release(taskPrincipal);
2477+
if (taskLogonTrigger)
2478+
ILogonTrigger_Release(taskLogonTrigger);
2479+
if (taskTrigger)
2480+
ITrigger_Release(taskTrigger);
2481+
if (taskTriggerCollection)
2482+
ITriggerCollection_Release(taskTriggerCollection);
2483+
if (taskSettings)
2484+
ITaskSettings_Release(taskSettings);
2485+
if (taskDefinition)
2486+
ITaskDefinition_Release(taskDefinition);
2487+
if (taskFolder)
2488+
ITaskFolder_Release(taskFolder);
2489+
if (taskService)
2490+
ITaskService_Release(taskService);
2491+
2492+
return status;
2493+
}

ProcessHacker/include/appsup.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,19 @@ HBITMAP PhGetShieldBitmap(
440440
VOID
441441
);
442442

443+
HRESULT PhRunAsAdminTask(
444+
_In_ PWSTR TaskName
445+
);
446+
447+
HRESULT PhDeleteAdminTask(
448+
_In_ PWSTR TaskName
449+
);
450+
451+
HRESULT PhCreateAdminTask(
452+
_In_ PWSTR TaskName,
453+
_In_ PWSTR FileName
454+
);
455+
443456
#define PH_LOAD_SHARED_ICON_SMALL(BaseAddress, Name) PhLoadIcon(BaseAddress, (Name), PH_LOAD_ICON_SHARED | PH_LOAD_ICON_SIZE_SMALL, 0, 0) // phapppub
444457
#define PH_LOAD_SHARED_ICON_LARGE(BaseAddress, Name) PhLoadIcon(BaseAddress, (Name), PH_LOAD_ICON_SHARED | PH_LOAD_ICON_SIZE_LARGE, 0, 0) // phapppub
445458

ProcessHacker/main.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* main program
44
*
55
* Copyright (C) 2009-2016 wj32
6-
* Copyright (C) 2017-2019 dmex
6+
* Copyright (C) 2017-2020 dmex
77
*
88
* This file is part of Process Hacker.
99
*
@@ -152,6 +152,21 @@ INT WINAPI wWinMain(
152152
PhActivatePreviousInstance();
153153
}
154154

155+
if (PhGetIntegerSetting(L"EnableStartAsAdmin") &&
156+
!PhStartupParameters.NewInstance &&
157+
!PhStartupParameters.ShowOptions &&
158+
!PhStartupParameters.CommandMode &&
159+
!PhStartupParameters.PhSvc)
160+
{
161+
if (!PhGetOwnTokenAttributes().Elevated)
162+
{
163+
if (SUCCEEDED(PhRunAsAdminTask(L"ProcessHackerTaskAdmin")))
164+
{
165+
RtlExitUserProcess(STATUS_SUCCESS);
166+
}
167+
}
168+
}
169+
155170
if (PhGetIntegerSetting(L"EnableKph") &&
156171
!PhStartupParameters.NoKph &&
157172
!PhStartupParameters.CommandMode &&

0 commit comments

Comments
 (0)