From: Tim Clem tclem@codeweavers.com
--- dlls/ntdll/unix/process.c | 9 +++++++++ dlls/wow64/process.c | 1 + include/winternl.h | 1 + programs/explorer/desktop.c | 6 ++++++ server/process.c | 27 +++++++++++++++++++++++++++ server/protocol.def | 6 ++++++ 6 files changed, 50 insertions(+)
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 6872a2460b2..c3a730379a4 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -1837,6 +1837,15 @@ NTSTATUS WINAPI NtSetInformationProcess( HANDLE handle, PROCESSINFOCLASS class, SERVER_END_REQ; return ret;
+ case ProcessWineGrantAdminToken: + SERVER_START_REQ( grant_process_admin_token ) + { + req->handle = wine_server_obj_handle( handle ); + ret = wine_server_call( req ); + } + SERVER_END_REQ; + break; + case ProcessPowerThrottlingState: FIXME( "ProcessPowerThrottlingState - stub\n" ); return STATUS_SUCCESS; diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index 0153dba3433..4d067cea06f 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -872,6 +872,7 @@ NTSTATUS WINAPI wow64_NtSetInformationProcess( UINT *args ) case ProcessPagePriority: /* MEMORY_PRIORITY_INFORMATION */ case ProcessPowerThrottlingState: /* PROCESS_POWER_THROTTLING_STATE */ case ProcessLeapSecondInformation: /* PROCESS_LEAP_SECOND_INFO */ + case ProcessWineGrantAdminToken: /* NULL */ return NtSetInformationProcess( handle, class, ptr, len );
case ProcessAccessToken: /* PROCESS_ACCESS_TOKEN */ diff --git a/include/winternl.h b/include/winternl.h index a1e6cca2251..0bae9fbf385 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1897,6 +1897,7 @@ typedef enum _PROCESSINFOCLASS { #ifdef __WINESRC__ ProcessWineMakeProcessSystem = 1000, ProcessWineLdtCopy, + ProcessWineGrantAdminToken, #endif } PROCESSINFOCLASS;
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index e526b468b7d..e0b57a4b37f 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -24,6 +24,7 @@ #define COBJMACROS #define OEMRESOURCE #include <windows.h> +#include <winternl.h> #include <rpc.h> #include <shlobj.h> #include <shellapi.h> @@ -1208,6 +1209,7 @@ void manage_desktop( WCHAR *arg ) HMODULE shell32; HANDLE thread; DWORD id; + NTSTATUS status;
/* get the rest of the command line (if any) */ while (*p && !is_whitespace(*p)) p++; @@ -1260,6 +1262,10 @@ void manage_desktop( WCHAR *arg ) SetThreadDesktop( desktop ); }
+ /* the desktop process should always have an admin token */ + status = NtSetInformationProcess( GetCurrentProcess(), ProcessWineGrantAdminToken, NULL, 0 ); + if (status) WARN( "couldn't set admin token for desktop, error %08lx\n", status ); + /* create the desktop window */ hwnd = CreateWindowExW( 0, DESKTOP_CLASS_ATOM, NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, &guid ); diff --git a/server/process.c b/server/process.c index 737b37d9441..00aa6a18f1f 100644 --- a/server/process.c +++ b/server/process.c @@ -1721,6 +1721,33 @@ DECL_HANDLER(make_process_system) release_object( process ); }
+/* grant a process a primary admin token with Default elevation */ +DECL_HANDLER(grant_process_admin_token) +{ + struct process *process; + struct token *token; + + if (!(process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION ))) + { + set_error( STATUS_INVALID_HANDLE ); + return; + } + + token = token_create_admin( TRUE, SecurityIdentification, + TokenElevationTypeDefault, default_session_id ); + if (!token) + { + release_object( process ); + set_error( STATUS_UNSUCCESSFUL ); + return; + } + + release_object( process->token ); + process->token = token; + + release_object( process ); +} + /* create a new job object */ DECL_HANDLER(create_job) { diff --git a/server/protocol.def b/server/protocol.def index bd0307c5d79..4b9c4dc8e5c 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3755,6 +3755,12 @@ struct handle_info @END
+/* Grant the given process an admin token with Default elevation */ +@REQ(grant_process_admin_token) + obj_handle_t handle; /* handle to the process */ +@END + + /* Get detailed fixed-size information about a token */ @REQ(get_token_info) obj_handle_t handle; /* handle to the object */