00054 :
00055
00056 This function locates
the specified system environment variable and
00057
return its value.
00058
00059 N.B. This service requires
the system environment privilege.
00060
00061 Arguments:
00062
00063 Variable - Supplies a pointer to a UNICODE descriptor
for the specified
00064 system environment variable.
00065
00066 Value - Supplies a pointer to a buffer that receives
the value of
the
00067 specified system environment variable.
00068
00069 ValueLength - Supplies
the length of
the value buffer in bytes.
00070
00071 ReturnLength - Supplies an optional pointer to a variable that receives
00072
the length of
the system environment variable value.
00073
00074 Return Value:
00075
00076 STATUS_SUCCESS
is returned
if the service
is successfully executed.
00077
00078 STATUS_PRIVILEGE_NOT_HELD
is returned
if the caller does not have
the
00079 privilege to query a system environment variable.
00080
00081 STATUS_ACCESS_VIOLATION
is returned
if the output parameter
for the
00082 system environment value or
the return length cannot be written,
00083 or
the descriptor or
the name of
the system environment variable
00084 cannot be read.
00085
00086 STATUS_INSUFFICIENT_RESOURCES - Insufficient system resources exist
00087
for this request to complete.
00088
00089 STATUS_UNSUCCESSFUL - The specified environment variable could not
00090 be located.
00091
00092 --*/
00093
00094 {
00095
00096 ULONG AnsiLength;
00097 ANSI_STRING AnsiString;
00098
ARC_STATUS ArcStatus;
00099 BOOLEAN HasPrivilege;
00100
NTSTATUS NtStatus;
00101
KPROCESSOR_MODE PreviousMode;
00102 UNICODE_STRING UnicodeString;
00103 PCHAR
ValueBuffer;
00104
00105
00106
00107
00108
00109 AnsiString.Buffer =
NULL;
00110
00111
00112
00113
00114
00115
00116
00117
00118
try {
00119
00120
00121
00122
00123
00124 PreviousMode = KeGetPreviousMode();
00125
if (PreviousMode !=
KernelMode) {
00126
00127
00128
00129
00130
00131
00132
ProbeForRead((PVOID)VariableName,
00133
sizeof(UNICODE_STRING),
00134
sizeof(ULONG));
00135
00136 UnicodeString = *VariableName;
00137
00138
00139
00140
00141
00142
if (UnicodeString.Length == 0) {
00143
return STATUS_ACCESS_VIOLATION;
00144 }
00145
00146
ProbeForRead((PVOID)UnicodeString.Buffer,
00147 UnicodeString.Length,
00148
sizeof(WCHAR));
00149
00150
00151
00152
00153
00154
ProbeForWrite((PVOID)VariableValue, ValueLength,
sizeof(WCHAR));
00155
00156
00157
00158
00159
00160
if (ARGUMENT_PRESENT(ReturnLength)) {
00161
ProbeForWriteUshort(ReturnLength);
00162 }
00163
00164
00165
00166
00167
00168
00169 HasPrivilege =
SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
00170 PreviousMode);
00171
00172
if (HasPrivilege ==
FALSE) {
00173
return(STATUS_PRIVILEGE_NOT_HELD);
00174 }
00175
00176 }
else {
00177 UnicodeString = *VariableName;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186 AnsiLength = RtlUnicodeStringToAnsiSize(&UnicodeString);
00187 AnsiString.Buffer = (PCHAR)
ExAllocatePoolWithTag(NonPagedPool, AnsiLength, 'rvnE');
00188
if (AnsiString.Buffer ==
NULL) {
00189
return STATUS_INSUFFICIENT_RESOURCES;
00190 }
00191
00192 AnsiString.MaximumLength = (
USHORT)AnsiLength;
00193 NtStatus =
RtlUnicodeStringToAnsiString(&AnsiString,
00194 &UnicodeString,
00195 FALSE);
00196
00197
if (
NT_SUCCESS(NtStatus) ==
FALSE) {
00198
ExFreePool((PVOID)AnsiString.Buffer);
00199
return NtStatus;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 } except (EXCEPTION_EXECUTE_HANDLER) {
00211
if (AnsiString.Buffer !=
NULL) {
00212
ExFreePool((PVOID)AnsiString.Buffer);
00213 }
00214
00215
return GetExceptionCode();
00216 }
00217
00218
00219
00220
00221
00222
ValueBuffer = (PCHAR)
ExAllocatePoolWithTag(NonPagedPool, MAXIMUM_ENVIRONMENT_VALUE, 'rvnE');
00223
if (
ValueBuffer ==
NULL) {
00224
ExFreePool((PVOID)AnsiString.Buffer);
00225
return STATUS_INSUFFICIENT_RESOURCES;
00226 }
00227
00228
00229
00230
00231
00232 ExAcquireFastMutex(&ExpEnvironmentLock);
00233 ArcStatus =
HalGetEnvironmentVariable(AnsiString.Buffer,
00234 MAXIMUM_ENVIRONMENT_VALUE,
00235 ValueBuffer);
00236
00237 ExReleaseFastMutex(&ExpEnvironmentLock);
00238
00239
00240
00241
00242
00243
ExFreePool((PVOID)AnsiString.Buffer);
00244
00245
00246
00247
00248
00249
00250
if (ArcStatus !=
ESUCCESS) {
00251
ExFreePool((PVOID)ValueBuffer);
00252
return STATUS_UNSUCCESSFUL;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
try {
00262
00263
00264
00265
00266
00267
00268
00269
RtlInitString(&AnsiString, ValueBuffer);
00270 UnicodeString.Buffer = (PWSTR)VariableValue;
00271 UnicodeString.MaximumLength = ValueLength;
00272 NtStatus =
RtlAnsiStringToUnicodeString(&UnicodeString,
00273 &AnsiString,
00274 FALSE);
00275
00276
00277
00278
00279
00280
00281
if (ARGUMENT_PRESENT(ReturnLength)) {
00282 *ReturnLength = UnicodeString.Length;
00283 }
00284
00285
00286
00287
00288
00289
ExFreePool((PVOID)ValueBuffer);
00290
return NtStatus;
00291
00292
00293
00294
00295
00296
00297
00298 } except (EXCEPTION_EXECUTE_HANDLER) {
00299
ExFreePool((PVOID)ValueBuffer);
00300
return GetExceptionCode();
00301 }
00302 }