-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathNtUtils.Environment.User.pas
More file actions
119 lines (90 loc) · 2.86 KB
/
NtUtils.Environment.User.pas
File metadata and controls
119 lines (90 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
unit NtUtils.Environment.User;
{
The functions for constructing user environment using a token.
}
interface
uses
Ntapi.ntseapi, Ntapi.Versions, NtUtils;
const
TOKEN_CREATE_ENVIRONMEMT = TOKEN_QUERY or TOKEN_DUPLICATE or TOKEN_IMPERSONATE;
// Prepare an environment for a user. If the token is not specified, the
// function returns only system environmental variables
function UnvxCreateUserEnvironment(
out Environment: IEnvironment;
[opt, Access(TOKEN_CREATE_ENVIRONMEMT)] hxToken: IHandle = nil;
InheritCurrent: Boolean = False
): TNtxStatus;
// Update environment for an AppContainer
[MinOSVersion(OsWin10)]
function UnvxUpdateAppContainerEnvironment(
var Environment: IEnvironment;
[Access(TOKEN_QUERY)] const hxToken: IHandle;
[opt] const AppContainerSidOverride: ISid = nil
): TNtxStatus;
implementation
uses
Ntapi.WinNt, Ntapi.UserEnv, NtUtils.Ldr, NtUtils.Tokens, NtUtils.Tokens.Info,
NtUtils.Environment, NtUtils.Profiles.AppContainer;
{$BOOLEVAL OFF}
{$IFOPT R+}{$DEFINE R+}{$ENDIF}
{$IFOPT Q+}{$DEFINE Q+}{$ENDIF}
function UnvxCreateUserEnvironment;
var
hToken: THandle;
EnvBlock: PEnvironment;
begin
Result := LdrxCheckDelayedImport(delayed_CreateEnvironmentBlock);
if not Result.IsSuccess then
Exit;
if Assigned(hxToken) then
begin
// Add support for pseudo-handles
Result := NtxExpandToken(hxToken, TOKEN_CREATE_ENVIRONMEMT);
if not Result.IsSuccess then
Exit;
hToken := hxToken.Handle;
end
else
hToken := 0; // System environment only
Result.Location := 'CreateEnvironmentBlock';
if hToken <> 0 then
Result.LastCall.Expects<TTokenAccessMask>(TOKEN_CREATE_ENVIRONMEMT);
Result.Win32Result := CreateEnvironmentBlock(EnvBlock, hToken,
InheritCurrent);
if not Result.IsSuccess then
Exit;
// Capturing the buffer will look up its size
Environment := RtlxCaptureEnvironment(EnvBlock, 0);
end;
function UnvxUpdateAppContainerEnvironment;
var
AppContainer: ISid;
ProfilePath, TempPath: String;
begin
// Determine the AppContainer SID
if not Assigned(AppContainerSidOverride) then
begin
Result := NtxQuerySidToken(hxToken, TokenAppContainerSid, AppContainer);
if not Result.IsSuccess then
Exit;
// Nothing to do if not AppContaier
if not Assigned(AppContainer) then
Exit(NtxSuccess);
end
else
AppContainer := AppContainerSidOverride;
// Obtain the profile path
Result := UnvxQueryAppContainerPathFromToken(ProfilePath, hxToken,
AppContainer);
if not Result.IsSuccess then
Exit;
// Fix AppData
Result := RtlxSetVariableEnvironment('LOCALAPPDATA', ProfilePath, Environment);
// Fix Temp
TempPath := ProfilePath + '\Temp';
if Result.IsSuccess then
Result := RtlxSetVariableEnvironment('TEMP', TempPath, Environment);
if Result.IsSuccess then
Result := RtlxSetVariableEnvironment('TMP', TempPath, Environment);
end;
end.