Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

sysenv.c File Reference

#include "exp.h"
#include "arccodes.h"

Go to the source code of this file.

Defines

#define MAXIMUM_ENVIRONMENT_VALUE   1024

Functions

NTSTATUS NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName, OUT PWSTR VariableValue, IN USHORT ValueLength, OUT PUSHORT ReturnLength OPTIONAL)
NTSTATUS NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName, IN PUNICODE_STRING VariableValue)

Variables

FAST_MUTEX ExpEnvironmentLock


Define Documentation

#define MAXIMUM_ENVIRONMENT_VALUE   1024
 

Definition at line 36 of file sysenv.c.


Function Documentation

NTSTATUS NtQuerySystemEnvironmentValue IN PUNICODE_STRING  VariableName,
OUT PWSTR  VariableValue,
IN USHORT  ValueLength,
OUT PUSHORT ReturnLength  OPTIONAL
 

Definition at line 45 of file sysenv.c.

References ARC_STATUS, ESUCCESS, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExpEnvironmentLock, FALSE, HalGetEnvironmentVariable(), KernelMode, KPROCESSOR_MODE, MAXIMUM_ENVIRONMENT_VALUE, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ProbeForRead, ProbeForWrite(), ProbeForWriteUshort, RtlAnsiStringToUnicodeString(), RtlInitString(), RtlUnicodeStringToAnsiString(), SeSinglePrivilegeCheck(), SeSystemEnvironmentPrivilege, USHORT, and ValueBuffer.

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 // Clear address of ANSI buffer. 00107 // 00108 00109 AnsiString.Buffer = NULL; 00110 00111 // 00112 // Establish an exception handler and attempt to probe and read the 00113 // name of the specified system environment variable, and probe the 00114 // variable value buffer and return length. If the probe or read 00115 // attempt fails, then return the exception code as the service status. 00116 // 00117 00118 try { 00119 00120 // 00121 // Get previous processor mode and probe arguments if necessary. 00122 // 00123 00124 PreviousMode = KeGetPreviousMode(); 00125 if (PreviousMode != KernelMode) { 00126 00127 // 00128 // Probe and capture the string descriptor for the system 00129 // environment variable name. 00130 // 00131 00132 ProbeForRead((PVOID)VariableName, 00133 sizeof(UNICODE_STRING), 00134 sizeof(ULONG)); 00135 00136 UnicodeString = *VariableName; 00137 00138 // 00139 // Probe the system environment variable name. 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 // Probe the system environment value buffer. 00152 // 00153 00154 ProbeForWrite((PVOID)VariableValue, ValueLength, sizeof(WCHAR)); 00155 00156 // 00157 // If argument is present, probe the return length value. 00158 // 00159 00160 if (ARGUMENT_PRESENT(ReturnLength)) { 00161 ProbeForWriteUshort(ReturnLength); 00162 } 00163 00164 // 00165 // Check if the current thread has the privilege to query a system 00166 // environment variable. 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 // Compute the size of the ANSI variable name, allocate a nonpaged 00183 // buffer, and convert the specified UNICODE variable name to ANSI. 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 // If an exception occurs during the read of the variable descriptor, 00204 // the read of the variable name, the probe of the variable value, or 00205 // the probe of the return length, then always handle the exception, 00206 // free the ANSI string buffer if necessary, and return the exception 00207 // code as the status value. 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 // Allocate nonpaged pool to receive variable value. 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 // Get the system environment variable value. 00230 // 00231 00232 ExAcquireFastMutex(&ExpEnvironmentLock); 00233 ArcStatus = HalGetEnvironmentVariable(AnsiString.Buffer, 00234 MAXIMUM_ENVIRONMENT_VALUE, 00235 ValueBuffer); 00236 00237 ExReleaseFastMutex(&ExpEnvironmentLock); 00238 00239 // 00240 // Free the ANSI string buffer used to hold the variable name. 00241 // 00242 00243 ExFreePool((PVOID)AnsiString.Buffer); 00244 00245 // 00246 // If the specified environment variable was not found, then free 00247 // the value buffer and return an unsuccessful status. 00248 // 00249 00250 if (ArcStatus != ESUCCESS) { 00251 ExFreePool((PVOID)ValueBuffer); 00252 return STATUS_UNSUCCESSFUL; 00253 } 00254 00255 // 00256 // Establish an exception handler and attempt to write the value of the 00257 // specified system environment variable. If the write attempt fails, 00258 // then return the exception code as the service status. 00259 // 00260 00261 try { 00262 00263 // 00264 // Initialize an ANSI string descriptor, set the maximum length and 00265 // buffer address for a UNICODE string descriptor, and convert the 00266 // ANSI variable value to UNICODE. 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 // If argument is present, then write the length of the UNICODE 00278 // variable value. 00279 // 00280 00281 if (ARGUMENT_PRESENT(ReturnLength)) { 00282 *ReturnLength = UnicodeString.Length; 00283 } 00284 00285 // 00286 // Free the value buffer used to hold the variable value. 00287 // 00288 00289 ExFreePool((PVOID)ValueBuffer); 00290 return NtStatus; 00291 00292 // 00293 // If an exception occurs during the write of the variable value, or 00294 // the write of the return length, then always handle the exception 00295 // and return the exception code as the status value. 00296 // 00297 00298 } except (EXCEPTION_EXECUTE_HANDLER) { 00299 ExFreePool((PVOID)ValueBuffer); 00300 return GetExceptionCode(); 00301 } 00302 }

NTSTATUS NtSetSystemEnvironmentValue IN PUNICODE_STRING  VariableName,
IN PUNICODE_STRING  VariableValue
 

Definition at line 305 of file sysenv.c.

References ARC_STATUS, ESUCCESS, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExpEnvironmentLock, FALSE, HalSetEnvironmentVariable(), KernelMode, KPROCESSOR_MODE, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ProbeForRead, RtlUnicodeStringToAnsiString(), SeSinglePrivilegeCheck(), SeSystemEnvironmentPrivilege, and USHORT.

00312 : 00313 00314 This function sets the specified system environment variable to the 00315 specified value. 00316 00317 N.B. This service requires the system environment privilege. 00318 00319 Arguments: 00320 00321 Variable - Supplies a pointer to a UNICODE descriptor for the specified 00322 system environment variable name. 00323 00324 Value - Supplies a pointer to a UNICODE descriptor for the specified 00325 system environment variable value. 00326 00327 Return Value: 00328 00329 STATUS_SUCCESS is returned if the service is successfully executed. 00330 00331 STATUS_PRIVILEGE_NOT_HELD is returned if the caller does not have the 00332 privilege to set a system environment variable. 00333 00334 STATUS_ACCESS_VIOLATION is returned if the input parameter for the 00335 system environment variable or value cannot be read. 00336 00337 STATUS_INSUFFICIENT_RESOURCES - Insufficient system resources exist 00338 for this request to complete. 00339 00340 --*/ 00341 00342 { 00343 00344 ULONG AnsiLength1; 00345 ULONG AnsiLength2; 00346 ANSI_STRING AnsiString1; 00347 ANSI_STRING AnsiString2; 00348 ARC_STATUS ArcStatus; 00349 BOOLEAN HasPrivilege; 00350 KPROCESSOR_MODE PreviousMode; 00351 NTSTATUS NtStatus; 00352 UNICODE_STRING UnicodeString1; 00353 UNICODE_STRING UnicodeString2; 00354 00355 // 00356 // Clear address of ANSI buffers. 00357 // 00358 00359 AnsiString1.Buffer = NULL; 00360 AnsiString2.Buffer = NULL; 00361 00362 // 00363 // Establish an exception handler and attempt to set the value of the 00364 // specified system environment variable. If the read attempt for the 00365 // system environment variable or value fails, then return the exception 00366 // code as the service status. Otherwise, return either success or access 00367 // denied as the service status. 00368 // 00369 00370 try { 00371 00372 // 00373 // Get previous processor mode and probe arguments if necessary. 00374 // 00375 00376 PreviousMode = KeGetPreviousMode(); 00377 if (PreviousMode != KernelMode) { 00378 00379 // 00380 // Probe and capture the string descriptor for the system 00381 // environment variable name. 00382 // 00383 00384 ProbeForRead((PVOID)VariableName, 00385 sizeof(UNICODE_STRING), 00386 sizeof(ULONG)); 00387 00388 UnicodeString1 = *VariableName; 00389 00390 // 00391 // Handle a zero length string explicitly since probing does not, 00392 // the error code is unusual, but it's what we would have done with 00393 // the HAL return code too. 00394 // 00395 00396 if (UnicodeString1.Length == 0) { 00397 return STATUS_INSUFFICIENT_RESOURCES; 00398 } 00399 00400 // 00401 // Probe the system environment variable name. 00402 // 00403 00404 ProbeForRead((PVOID)UnicodeString1.Buffer, 00405 UnicodeString1.Length, 00406 sizeof(WCHAR)); 00407 00408 // 00409 // Probe and capture the string descriptor for the system 00410 // environment variable value. 00411 // 00412 00413 ProbeForRead((PVOID)VariableValue, 00414 sizeof(UNICODE_STRING), 00415 sizeof(ULONG)); 00416 00417 UnicodeString2 = *VariableValue; 00418 00419 // 00420 // Handle a zero length string explicitly since probing does not 00421 // the error code is unusual, but it's what we would have done with 00422 // the HAL return code too. 00423 // 00424 00425 if (UnicodeString2.Length == 0) { 00426 return STATUS_INSUFFICIENT_RESOURCES; 00427 } 00428 00429 // 00430 // Probe the system environment variable value. 00431 // 00432 00433 ProbeForRead((PVOID)UnicodeString2.Buffer, 00434 UnicodeString2.Length, 00435 sizeof(WCHAR)); 00436 00437 // 00438 // Check if the current thread has the privilege to query a system 00439 // environment variable. 00440 // 00441 00442 HasPrivilege = SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege, 00443 PreviousMode); 00444 00445 if (HasPrivilege == FALSE) { 00446 return(STATUS_PRIVILEGE_NOT_HELD); 00447 } 00448 00449 } else { 00450 UnicodeString1 = *VariableName; 00451 UnicodeString2 = *VariableValue; 00452 } 00453 00454 00455 // 00456 // Compute the size of the ANSI variable name, allocate a nonpaged 00457 // buffer, and convert the specified UNICODE variable name to ANSI. 00458 // 00459 00460 AnsiLength1 = RtlUnicodeStringToAnsiSize(&UnicodeString1); 00461 AnsiString1.Buffer = (PCHAR)ExAllocatePoolWithTag(NonPagedPool, AnsiLength1, 'rvnE'); 00462 if (AnsiString1.Buffer == NULL) { 00463 return STATUS_INSUFFICIENT_RESOURCES; 00464 } 00465 00466 AnsiString1.MaximumLength = (USHORT)AnsiLength1; 00467 NtStatus = RtlUnicodeStringToAnsiString(&AnsiString1, 00468 &UnicodeString1, 00469 FALSE); 00470 00471 if (NT_SUCCESS(NtStatus) == FALSE) { 00472 ExFreePool((PVOID)AnsiString1.Buffer); 00473 return NtStatus; 00474 } 00475 00476 // 00477 // Compute the size of the ANSI variable value, allocate a nonpaged 00478 // buffer, and convert the specified UNICODE variable value to ANSI. 00479 // 00480 00481 AnsiLength2 = RtlUnicodeStringToAnsiSize(&UnicodeString2); 00482 AnsiString2.Buffer = (PCHAR)ExAllocatePoolWithTag(NonPagedPool, AnsiLength2, 'rvnE'); 00483 if (AnsiString2.Buffer == NULL) { 00484 ExFreePool((PVOID)AnsiString1.Buffer); 00485 return STATUS_INSUFFICIENT_RESOURCES; 00486 } 00487 00488 AnsiString2.MaximumLength = (USHORT)AnsiLength2; 00489 NtStatus = RtlUnicodeStringToAnsiString(&AnsiString2, 00490 &UnicodeString2, 00491 FALSE); 00492 00493 if (NT_SUCCESS(NtStatus) == FALSE) { 00494 ExFreePool((PVOID)AnsiString1.Buffer); 00495 ExFreePool((PVOID)AnsiString2.Buffer); 00496 return NtStatus; 00497 } 00498 00499 // 00500 // If an exception occurs during the read of the variable descriptor, 00501 // the read of the variable name, the read of the value descriptor, or 00502 // the read of the value, then always handle the exception, free the 00503 // ANSI string buffers if necessary, and return the exception code as 00504 // the status value. 00505 // 00506 00507 } except (EXCEPTION_EXECUTE_HANDLER) { 00508 if (AnsiString1.Buffer != NULL) { 00509 ExFreePool((PVOID)AnsiString1.Buffer); 00510 } 00511 00512 if (AnsiString2.Buffer != NULL) { 00513 ExFreePool((PVOID)AnsiString2.Buffer); 00514 } 00515 00516 return GetExceptionCode(); 00517 } 00518 00519 // 00520 // Set the system environment variable value. 00521 // 00522 00523 ExAcquireFastMutex(&ExpEnvironmentLock); 00524 ArcStatus = HalSetEnvironmentVariable(AnsiString1.Buffer, 00525 AnsiString2.Buffer); 00526 00527 ExReleaseFastMutex(&ExpEnvironmentLock); 00528 00529 // 00530 // Free the ANSI string buffers used to hold the variable name and value. 00531 // 00532 00533 ExFreePool((PVOID)AnsiString1.Buffer); 00534 ExFreePool((PVOID)AnsiString2.Buffer); 00535 00536 // 00537 // If the specified value of the specified environment variable was 00538 // successfully set, then return a success status. Otherwise, return 00539 // insufficient resources. 00540 // 00541 00542 if (ArcStatus == ESUCCESS) { 00543 return STATUS_SUCCESS; 00544 00545 } else { 00546 return STATUS_INSUFFICIENT_RESOURCES; 00547 } 00548 } }


Variable Documentation

FAST_MUTEX ExpEnvironmentLock
 

Definition at line 42 of file sysenv.c.

Referenced by NtQuerySystemEnvironmentValue(), and NtSetSystemEnvironmentValue().


Generated on Sat May 15 19:45:43 2004 for test by doxygen 1.3.7