From: Tim Clem tclem@codeweavers.com
--- dlls/ntdll/unix/process.c | 13 +++++++++++++ dlls/wow64/process.c | 1 + include/winternl.h | 1 + programs/explorer/desktop.c | 6 ++++++ server/protocol.def | 7 +++++++ server/token.c | 16 ++++++++++++++++ 6 files changed, 44 insertions(+)
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index f3551c2e7d7..674d0d0068d 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -1775,6 +1775,19 @@ NTSTATUS WINAPI NtSetInformationProcess( HANDLE handle, PROCESSINFOCLASS class, SERVER_END_REQ; return ret;
+ case ProcessWineSetAdminToken: + SERVER_START_REQ( create_primary_admin_token ) + { + if (!(ret = wine_server_call( req ))) + { + HANDLE token = wine_server_ptr_handle( reply->token ); + PROCESS_ACCESS_TOKEN info = { .Token = token, .Thread = NULL }; + ret = NtSetInformationProcess( handle, ProcessAccessToken, &info, sizeof(info) ); + } + } + SERVER_END_REQ; + return ret; + case ProcessPowerThrottlingState: FIXME( "ProcessPowerThrottlingState - stub\n" ); return STATUS_SUCCESS; diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index 4f6233002bc..1c0057eff9a 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -871,6 +871,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 ProcessWineSetAdminToken: /* NULL */ return NtSetInformationProcess( handle, class, ptr, len );
case ProcessAccessToken: /* PROCESS_ACCESS_TOKEN */ diff --git a/include/winternl.h b/include/winternl.h index 4f24a921bb1..1f4fdc172bd 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1897,6 +1897,7 @@ typedef enum _PROCESSINFOCLASS { #ifdef __WINESRC__ ProcessWineMakeProcessSystem = 1000, ProcessWineLdtCopy, + ProcessWineSetAdminToken, #endif } PROCESSINFOCLASS;
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 800b03f48bf..1e70a5b74da 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(), ProcessWineSetAdminToken, 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/protocol.def b/server/protocol.def index c6af7379f17..a7a89724d31 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3279,6 +3279,13 @@ enum caret_state @END
+/* Create a new primary admin token with Default elevation. */ +@REQ(create_primary_admin_token) +@REPLY + obj_handle_t token; /* handle to the token */ +@END + + /* Open a security token */ @REQ(open_token) obj_handle_t handle; /* handle to the thread or process */ diff --git a/server/token.c b/server/token.c index 48ee1eca8fe..698b2627ccb 100644 --- a/server/token.c +++ b/server/token.c @@ -1209,6 +1209,22 @@ DECL_HANDLER(create_token) }
+/* create a new primary admin token with Default elevation */ +DECL_HANDLER(create_primary_admin_token) +{ + struct token *token = token_create_admin( TRUE, SecurityIdentification, + TokenElevationTypeDefault, default_session_id ); + if (!token) + { + set_error( STATUS_UNSUCCESSFUL ); + return; + } + + reply->token = alloc_handle( current->process, token, TOKEN_ALL_ACCESS, 0 ); + release_object( token ); +} + + /* open a security token */ DECL_HANDLER(open_token) {