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

environ.c File Reference

#include "ntrtlp.h"
#include "zwapi.h"
#include "nturtl.h"
#include "string.h"

Go to the source code of this file.

Functions

NTSTATUS RtlCreateEnvironment (IN BOOLEAN CloneCurrentEnvironment OPTIONAL, OUT PVOID *Environment)
NTSTATUS RtlDestroyEnvironment (IN PVOID Environment)
NTSTATUS RtlSetCurrentEnvironment (IN PVOID Environment, OUT PVOID *PreviousEnvironment OPTIONAL)
NTSTATUS RtlQueryEnvironmentVariable_U (IN PVOID Environment OPTIONAL, IN PUNICODE_STRING Name, IN OUT PUNICODE_STRING Value)
NTSTATUS RtlSetEnvironmentVariable (IN OUT PVOID *Environment OPTIONAL, IN PUNICODE_STRING Name, IN PUNICODE_STRING Value OPTIONAL)

Variables

BOOLEAN RtlpEnvironCacheValid
UNICODE_STRING RtlpEnvironCacheName
UNICODE_STRING RtlpEnvironCacheValue


Function Documentation

NTSTATUS RtlCreateEnvironment IN BOOLEAN CloneCurrentEnvironment  OPTIONAL,
OUT PVOID *  Environment
 

Definition at line 35 of file environ.c.

References NT_SUCCESS, NTSTATUS(), NULL, RtlAcquirePebLock(), RtlReleasePebLock(), and Status.

Referenced by main().

00039 { 00040 NTSTATUS Status; 00041 MEMORY_BASIC_INFORMATION MemoryInformation; 00042 PVOID pNew, pOld; 00043 00044 // 00045 // If not cloning a copy of the current process's environment variable 00046 // block, just allocate a block of committed memory and return its 00047 // address. 00048 // 00049 00050 pNew = NULL; 00051 if (!CloneCurrentEnvironment) { 00052 createEmptyEnvironment: 00053 MemoryInformation.RegionSize = 1; 00054 Status = ZwAllocateVirtualMemory( NtCurrentProcess(), 00055 &pNew, 00056 0, 00057 &MemoryInformation.RegionSize, 00058 MEM_COMMIT, 00059 PAGE_READWRITE 00060 ); 00061 if (NT_SUCCESS( Status )) { 00062 *Environment = pNew; 00063 } 00064 00065 return( Status ); 00066 } 00067 00068 // 00069 // Acquire the Peb Lock for the duration while we munge the environment 00070 // variable storage block. 00071 // 00072 00073 RtlAcquirePebLock(); 00074 00075 // 00076 // Capture the pointer to the current process's environment variable 00077 // block and initialize the new pointer to null for our finally clause. 00078 // 00079 00080 pOld = NtCurrentPeb()->ProcessParameters->Environment; 00081 if (pOld == NULL) { 00082 RtlReleasePebLock(); 00083 goto createEmptyEnvironment; 00084 } 00085 00086 try { 00087 // 00088 // Query the current size of the current process's environment 00089 // variable block. Return status if failure. 00090 // 00091 00092 Status = ZwQueryVirtualMemory( NtCurrentProcess(), 00093 pOld, 00094 MemoryBasicInformation, 00095 &MemoryInformation, 00096 sizeof( MemoryInformation ), 00097 NULL 00098 ); 00099 if (!NT_SUCCESS( Status )) { 00100 return( Status ); 00101 } 00102 00103 // 00104 // Allocate memory to contain a copy of the current process's 00105 // environment variable block. Return status if failure. 00106 // 00107 00108 Status = ZwAllocateVirtualMemory( NtCurrentProcess(), 00109 &pNew, 00110 0, 00111 &MemoryInformation.RegionSize, 00112 MEM_COMMIT, 00113 PAGE_READWRITE 00114 ); 00115 if (!NT_SUCCESS( Status )) { 00116 return( Status ); 00117 } 00118 00119 // 00120 // Copy the current process's environment to the allocated memory 00121 // and return a pointer to the copy. 00122 // 00123 00124 RtlMoveMemory( pNew, pOld, MemoryInformation.RegionSize ); 00125 *Environment = pNew; 00126 } 00127 finally { 00128 if (AbnormalTermination()) { 00129 Status = STATUS_ACCESS_VIOLATION; 00130 if (pNew != NULL) { 00131 ZwFreeVirtualMemory( NtCurrentProcess(), 00132 &pNew, 00133 &MemoryInformation.RegionSize, 00134 MEM_RELEASE 00135 ); 00136 } 00137 } 00138 00139 RtlReleasePebLock(); 00140 } 00141 00142 return( Status ); 00143 }

NTSTATUS RtlDestroyEnvironment IN PVOID  Environment  ) 
 

Definition at line 147 of file environ.c.

References NTSTATUS(), and Status.

Referenced by RtlSetCurrentEnvironment().

00150 { 00151 NTSTATUS Status; 00152 SIZE_T RegionSize; 00153 00154 // 00155 // Free the specified environment variable block. 00156 // 00157 00158 RegionSize = 0; 00159 Status = ZwFreeVirtualMemory( NtCurrentProcess(), 00160 &Environment, 00161 &RegionSize, 00162 MEM_RELEASE 00163 ); 00164 // 00165 // Return status. 00166 // 00167 00168 return( Status ); 00169 }

NTSTATUS RtlQueryEnvironmentVariable_U IN PVOID Environment  OPTIONAL,
IN PUNICODE_STRING  Name,
IN OUT PUNICODE_STRING  Value
 

Definition at line 250 of file environ.c.

References DbgPrint, L, Name, NTSTATUS(), NULL, RtlAcquirePebLock(), RtlEqualUnicodeString(), RtlpEnvironCacheName, RtlpEnvironCacheValid, RtlpEnvironCacheValue, RtlReleasePebLock(), Status, TRUE, and USHORT.

Referenced by LdrQueryApplicationCompatibilityGoo(), RtlExpandEnvironmentStrings_U(), RtlGetFullPathName_Ustr(), and RtlpCheckRelativeDrive().

00255 { 00256 NTSTATUS Status; 00257 UNICODE_STRING CurrentName; 00258 UNICODE_STRING CurrentValue; 00259 PWSTR p; 00260 PPEB Peb; 00261 00262 Status = STATUS_VARIABLE_NOT_FOUND; 00263 Peb = NtCurrentPeb(); 00264 00265 try { 00266 if (ARGUMENT_PRESENT( Environment )) { 00267 p = Environment; 00268 if (*p == UNICODE_NULL) { 00269 leave; 00270 } 00271 } 00272 else { 00273 // 00274 // Acquire the Peb Lock for the duration while we munge the 00275 // environment variable storage block. 00276 // 00277 00278 RtlAcquirePebLock(); 00279 00280 // 00281 // Capture the pointer to the current process's environment variable 00282 // block. 00283 // 00284 00285 p = Peb->ProcessParameters->Environment; 00286 00287 } 00288 #if DBG 00289 if (*p == UNICODE_NULL) 00290 DbgPrint( "RTL: QEV - Empty Environment being searched: %08x\n", p); 00291 else if ((UCHAR)((*p) >> 8) != '\0') 00292 DbgPrint( "RTL: QEV - Possible ANSI Environment being searched: %08x\n", p); 00293 #endif 00294 00295 if ( RtlpEnvironCacheValid && p == Peb->ProcessParameters->Environment ) { 00296 if (RtlEqualUnicodeString( Name, &RtlpEnvironCacheName, TRUE )) { 00297 00298 // 00299 // Names are equal. Always return the length of the 00300 // value string, excluding the terminating null. If 00301 // there is room in the caller's buffer, return a copy 00302 // of the value string and success status. Otherwise 00303 // return an error status. In the latter case, the caller 00304 // can examine the length field of their value string 00305 // so they can determine much memory is needed. 00306 // 00307 00308 Value->Length = RtlpEnvironCacheValue.Length; 00309 if (Value->MaximumLength >= RtlpEnvironCacheValue.Length) { 00310 RtlMoveMemory( Value->Buffer, 00311 RtlpEnvironCacheValue.Buffer, 00312 RtlpEnvironCacheValue.Length 00313 ); 00314 // 00315 // Null terminate returned string if there is room. 00316 // 00317 00318 if (Value->MaximumLength > RtlpEnvironCacheValue.Length) { 00319 Value->Buffer[ RtlpEnvironCacheValue.Length/sizeof(WCHAR) ] = L'\0'; 00320 } 00321 00322 Status = STATUS_SUCCESS; 00323 } 00324 else { 00325 Status = STATUS_BUFFER_TOO_SMALL; 00326 } 00327 goto environcachehit; 00328 } 00329 } 00330 00331 // 00332 // The environment variable block consists of zero or more null 00333 // terminated UNICODE strings. Each string is of the form: 00334 // 00335 // name=value 00336 // 00337 // where the null termination is after the value. 00338 // 00339 00340 if (p != NULL) while (*p) { 00341 // 00342 // Determine the size of the name and value portions of 00343 // the current string of the environment variable block. 00344 // 00345 00346 CurrentName.Buffer = p; 00347 CurrentName.Length = 0; 00348 CurrentName.MaximumLength = 0; 00349 while (*p) { 00350 // 00351 // If we see an equal sign, then compute the size of 00352 // the name portion and scan for the end of the value. 00353 // 00354 00355 if (*p == L'=' && p != CurrentName.Buffer) { 00356 CurrentName.Length = (USHORT)(p - CurrentName.Buffer)*sizeof(WCHAR); 00357 CurrentName.MaximumLength = (USHORT)(CurrentName.Length+sizeof(WCHAR)); 00358 CurrentValue.Buffer = ++p; 00359 00360 while(*p) { 00361 p++; 00362 } 00363 CurrentValue.Length = (USHORT)(p - CurrentValue.Buffer)*sizeof(WCHAR); 00364 CurrentValue.MaximumLength = (USHORT)(CurrentValue.Length+sizeof(WCHAR)); 00365 00366 // 00367 // At this point we have the length of both the name 00368 // and value portions, so exit the loop so we can 00369 // do the compare. 00370 // 00371 break; 00372 } 00373 else { 00374 p++; 00375 } 00376 } 00377 00378 // 00379 // Skip over the terminating null character for this name=value 00380 // pair in preparation for the next iteration of the loop. 00381 // 00382 00383 p++; 00384 00385 // 00386 // Compare the current name with the one requested, ignore 00387 // case. 00388 // 00389 00390 if (RtlEqualUnicodeString( Name, &CurrentName, TRUE )) { 00391 // 00392 // Names are equal. Always return the length of the 00393 // value string, excluding the terminating null. If 00394 // there is room in the caller's buffer, return a copy 00395 // of the value string and success status. Otherwise 00396 // return an error status. In the latter case, the caller 00397 // can examine the length field of their value string 00398 // so they can determine much memory is needed. 00399 // 00400 00401 Value->Length = CurrentValue.Length; 00402 if (Value->MaximumLength >= CurrentValue.Length) { 00403 RtlMoveMemory( Value->Buffer, 00404 CurrentValue.Buffer, 00405 CurrentValue.Length 00406 ); 00407 // 00408 // Null terminate returned string if there is room. 00409 // 00410 00411 if (Value->MaximumLength > CurrentValue.Length) { 00412 Value->Buffer[ CurrentValue.Length/sizeof(WCHAR) ] = L'\0'; 00413 } 00414 00415 if ( !Environment || Environment == Peb->ProcessParameters->Environment) { 00416 RtlpEnvironCacheValid = TRUE; 00417 RtlpEnvironCacheName = CurrentName; 00418 RtlpEnvironCacheValue = CurrentValue; 00419 } 00420 00421 Status = STATUS_SUCCESS; 00422 } 00423 else { 00424 Status = STATUS_BUFFER_TOO_SMALL; 00425 } 00426 break; 00427 } 00428 } 00429 environcachehit:; 00430 } 00431 finally { 00432 // 00433 // If abnormally terminating, assume access violation. 00434 // 00435 00436 if (AbnormalTermination()) { 00437 Status = STATUS_ACCESS_VIOLATION; 00438 } 00439 00440 // 00441 // Release the Peb lock. 00442 // 00443 00444 if (!ARGUMENT_PRESENT( Environment )) { 00445 RtlReleasePebLock(); 00446 } 00447 } 00448 00449 // 00450 // Return status. 00451 // 00452 00453 return( Status ); 00454 }

NTSTATUS RtlSetCurrentEnvironment IN PVOID  Environment,
OUT PVOID *PreviousEnvironment  OPTIONAL
 

Definition at line 173 of file environ.c.

References NTSTATUS(), NULL, RtlAcquirePebLock(), RtlDestroyEnvironment(), RtlReleasePebLock(), and Status.

00177 { 00178 NTSTATUS Status; 00179 PVOID pOld; 00180 00181 // 00182 // Acquire the Peb Lock for the duration while we munge the environment 00183 // variable storage block. 00184 // 00185 00186 RtlAcquirePebLock(); 00187 00188 Status = STATUS_SUCCESS; 00189 try { 00190 // 00191 // Capture current process's environment variable block pointer to 00192 // return to caller or destroy. 00193 // 00194 00195 pOld = NtCurrentPeb()->ProcessParameters->Environment; 00196 00197 // 00198 // Change current process's environment variable block pointer to 00199 // point to the passed block. 00200 // 00201 00202 00203 NtCurrentPeb()->ProcessParameters->Environment = Environment; 00204 00205 // 00206 // If caller requested it, return the pointer to the previous 00207 // process environment variable block and set the local variable 00208 // to NULL so we dont destroy it below. 00209 // 00210 00211 if (ARGUMENT_PRESENT( PreviousEnvironment )) { 00212 *PreviousEnvironment = pOld; 00213 pOld = NULL; 00214 } 00215 } 00216 finally { 00217 if (AbnormalTermination()) { 00218 Status = STATUS_ACCESS_VIOLATION; 00219 pOld = NULL; 00220 } 00221 } 00222 00223 // 00224 // Release the Peb Lock 00225 // 00226 00227 RtlReleasePebLock(); 00228 00229 00230 // 00231 // If old environment not returned to caller, destroy it. 00232 // 00233 00234 if (pOld != NULL) { 00235 RtlDestroyEnvironment( pOld ); 00236 } 00237 00238 // 00239 // Return status 00240 // 00241 00242 return( Status ); 00243 }

NTSTATUS RtlSetEnvironmentVariable IN OUT PVOID *Environment  OPTIONAL,
IN PUNICODE_STRING  Name,
IN PUNICODE_STRING Value  OPTIONAL
 

Definition at line 458 of file environ.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, L, n, Name, NT_SUCCESS, NTSTATUS(), NULL, RtlAcquirePebLock(), RtlCompareUnicodeString(), RtlpEnvironCacheValid, RtlReleasePebLock(), Size, Status, TRUE, and USHORT.

Referenced by RtlpResetDriveEnvironment(), and SetEnvironment().

00463 { 00464 NTSTATUS Status; 00465 MEMORY_BASIC_INFORMATION MemoryInformation; 00466 UNICODE_STRING CurrentName; 00467 UNICODE_STRING CurrentValue; 00468 PVOID pOld, pNew; 00469 ULONG n, Size; 00470 SIZE_T NewSize; 00471 LONG CompareResult; 00472 PWSTR p, pStart, pEnd; 00473 00474 // 00475 // Validate passed in name and reject if zero length or anything but the first 00476 // character is an equal sign. 00477 // 00478 n = Name->Length / sizeof( WCHAR ); 00479 if (n == 0) { 00480 return STATUS_INVALID_PARAMETER; 00481 } 00482 00483 try { 00484 p = Name->Buffer; 00485 while (--n) { 00486 if (*++p == L'=') { 00487 return STATUS_INVALID_PARAMETER; 00488 } 00489 } 00490 } 00491 except (EXCEPTION_EXECUTE_HANDLER) { 00492 return GetExceptionCode(); 00493 } 00494 00495 RtlpEnvironCacheValid = FALSE; 00496 Status = STATUS_VARIABLE_NOT_FOUND; 00497 if (ARGUMENT_PRESENT( Environment )) { 00498 pOld = *Environment; 00499 } 00500 else { 00501 // 00502 // Acquire the Peb Lock for the duration while we munge the 00503 // environment variable storage block. 00504 // 00505 00506 RtlAcquirePebLock(); 00507 00508 // 00509 // Capture the pointer to the current process's environment variable 00510 // block. 00511 // 00512 00513 pOld = NtCurrentPeb()->ProcessParameters->Environment; 00514 } 00515 pNew = NULL; 00516 00517 try { 00518 // 00519 // The environment variable block consists of zero or more null 00520 // terminated UNICODE strings. Each string is of the form: 00521 // 00522 // name=value 00523 // 00524 // where the null termination is after the value. 00525 // 00526 00527 p = pOld; 00528 pEnd = NULL; 00529 if (p != NULL) while (*p) { 00530 // 00531 // Determine the size of the name and value portions of 00532 // the current string of the environment variable block. 00533 // 00534 00535 CurrentName.Buffer = p; 00536 CurrentName.Length = 0; 00537 CurrentName.MaximumLength = 0; 00538 while (*p) { 00539 // 00540 // If we see an equal sign, then compute the size of 00541 // the name portion and scan for the end of the value. 00542 // 00543 00544 if (*p == L'=' && p != CurrentName.Buffer) { 00545 CurrentName.Length = (USHORT)(p - CurrentName.Buffer) * sizeof(WCHAR); 00546 CurrentName.MaximumLength = (USHORT)(CurrentName.Length+sizeof(WCHAR)); 00547 CurrentValue.Buffer = ++p; 00548 00549 while(*p) { 00550 p++; 00551 } 00552 CurrentValue.Length = (USHORT)(p - CurrentValue.Buffer) * sizeof(WCHAR); 00553 CurrentValue.MaximumLength = (USHORT)(CurrentValue.Length+sizeof(WCHAR)); 00554 00555 // 00556 // At this point we have the length of both the name 00557 // and value portions, so exit the loop so we can 00558 // do the compare. 00559 // 00560 break; 00561 } 00562 else { 00563 p++; 00564 } 00565 } 00566 00567 // 00568 // Skip over the terminating null character for this name=value 00569 // pair in preparation for the next iteration of the loop. 00570 // 00571 00572 p++; 00573 00574 // 00575 // Compare the current name with the one requested, ignore 00576 // case. 00577 // 00578 00579 if (!(CompareResult = RtlCompareUnicodeString( Name, &CurrentName, TRUE ))) { 00580 // 00581 // Names are equal. Now find the end of the current 00582 // environment variable block. 00583 // 00584 00585 pEnd = p; 00586 while (*pEnd) { 00587 while (*pEnd++) { 00588 } 00589 } 00590 pEnd++; 00591 00592 if (!ARGUMENT_PRESENT( Value )) { 00593 // 00594 // If the caller did not specify a new value, then delete 00595 // the entire name=value pair by copying up the remainder 00596 // of the environment variable block. 00597 // 00598 00599 RtlMoveMemory( CurrentName.Buffer, 00600 p, 00601 (ULONG) ((pEnd - p)*sizeof(WCHAR)) 00602 ); 00603 Status = STATUS_SUCCESS; 00604 } 00605 else 00606 if (Value->Length <= CurrentValue.Length) { 00607 // 00608 // New value is smaller, so copy new value, then null 00609 // terminate it, and then move up the remainder of the 00610 // variable block so it is immediately after the new 00611 // null terminated value. 00612 // 00613 00614 pStart = CurrentValue.Buffer; 00615 RtlMoveMemory( pStart, Value->Buffer, Value->Length ); 00616 pStart += Value->Length/sizeof(WCHAR); 00617 *pStart++ = L'\0'; 00618 00619 RtlMoveMemory( pStart, p,(ULONG)((pEnd - p)*sizeof(WCHAR)) ); 00620 Status = STATUS_SUCCESS; 00621 } 00622 else { 00623 // 00624 // New value is larger, so query the current size of the 00625 // environment variable block. Return status if failure. 00626 // 00627 00628 Status = ZwQueryVirtualMemory( NtCurrentProcess(), 00629 pOld, 00630 MemoryBasicInformation, 00631 &MemoryInformation, 00632 sizeof( MemoryInformation ), 00633 NULL 00634 ); 00635 if (!NT_SUCCESS( Status )) { 00636 return( Status ); 00637 } 00638 00639 // 00640 // See if there is room for new, larger value. If not 00641 // allocate a new copy of the environment variable 00642 // block. 00643 // 00644 00645 NewSize = (pEnd - (PWSTR)pOld)*sizeof(WCHAR) + 00646 Value->Length - CurrentValue.Length; 00647 if (NewSize >= MemoryInformation.RegionSize) { 00648 // 00649 // Allocate memory to contain a copy of the current 00650 // process's environment variable block. Return 00651 // status if failure. 00652 // 00653 00654 Status = ZwAllocateVirtualMemory( NtCurrentProcess(), 00655 &pNew, 00656 0, 00657 &NewSize, 00658 MEM_COMMIT, 00659 PAGE_READWRITE 00660 ); 00661 if (!NT_SUCCESS( Status )) { 00662 return( Status ); 00663 } 00664 00665 // 00666 // Copy the current process's environment to the allocated memory 00667 // inserting the new value as we do the copy. 00668 // 00669 00670 Size = (ULONG) (CurrentValue.Buffer - (PWSTR)pOld); 00671 RtlMoveMemory( pNew, pOld, Size*sizeof(WCHAR) ); 00672 pStart = (PWSTR)pNew + Size; 00673 RtlMoveMemory( pStart, Value->Buffer, Value->Length ); 00674 pStart += Value->Length/sizeof(WCHAR); 00675 *pStart++ = L'\0'; 00676 RtlMoveMemory( pStart, p,(ULONG)((pEnd - p)*sizeof(WCHAR))); 00677 if (ARGUMENT_PRESENT( Environment )) 00678 *Environment = pNew; 00679 else { 00680 NtCurrentPeb()->ProcessParameters->Environment = pNew; 00681 NtCurrentPeb()->EnvironmentUpdateCount += 1; 00682 } 00683 00684 ZwFreeVirtualMemory( NtCurrentProcess(), 00685 &pOld, 00686 &MemoryInformation.RegionSize, 00687 MEM_RELEASE 00688 ); 00689 pNew = pOld; 00690 } 00691 else { 00692 pStart = CurrentValue.Buffer + Value->Length/sizeof(WCHAR) + 1; 00693 RtlMoveMemory( pStart, p,(ULONG)((pEnd - p)*sizeof(WCHAR))); 00694 *--pStart = L'\0'; 00695 00696 RtlMoveMemory( pStart - Value->Length/sizeof(WCHAR), 00697 Value->Buffer, 00698 Value->Length 00699 ); 00700 } 00701 } 00702 00703 break; 00704 } 00705 else 00706 if (CompareResult < 0) { 00707 // 00708 // Request name is less than current name, then look no 00709 // further as we will not find it in our sorted list. 00710 // The insertion point for the new variable is before the 00711 // variable just examined. 00712 // 00713 00714 p = CurrentName.Buffer; 00715 break; 00716 } 00717 } 00718 00719 // 00720 // If variable name not found and a new value parameter was specified 00721 // then insert the new variable name and its value at the appropriate 00722 // place in the environment variable block (i.e. where p points to). 00723 // 00724 00725 if (pEnd == NULL && ARGUMENT_PRESENT( Value )) { 00726 if (p != NULL) { 00727 // 00728 // Name not found. Now find the end of the current 00729 // environment variable block. 00730 // 00731 00732 pEnd = p; 00733 while (*pEnd) { 00734 while (*pEnd++) { 00735 } 00736 } 00737 pEnd++; 00738 00739 // 00740 // New value is present, so query the current size of the 00741 // environment variable block. Return status if failure. 00742 // 00743 00744 Status = ZwQueryVirtualMemory( NtCurrentProcess(), 00745 pOld, 00746 MemoryBasicInformation, 00747 &MemoryInformation, 00748 sizeof( MemoryInformation ), 00749 NULL 00750 ); 00751 if (!NT_SUCCESS( Status )) { 00752 return( Status ); 00753 } 00754 00755 // 00756 // See if there is room for new, larger value. If not 00757 // allocate a new copy of the environment variable 00758 // block. 00759 // 00760 00761 NewSize = (pEnd - (PWSTR)pOld) * sizeof(WCHAR) + 00762 Name->Length + 00763 sizeof(WCHAR) + 00764 Value->Length + 00765 sizeof(WCHAR); 00766 } 00767 else { 00768 NewSize = Name->Length + 00769 sizeof(WCHAR) + 00770 Value->Length + 00771 sizeof(WCHAR); 00772 MemoryInformation.RegionSize = 0; 00773 } 00774 00775 if (NewSize >= MemoryInformation.RegionSize) { 00776 // 00777 // Allocate memory to contain a copy of the current 00778 // process's environment variable block. Return 00779 // status if failure. 00780 // 00781 00782 Status = ZwAllocateVirtualMemory( NtCurrentProcess(), 00783 &pNew, 00784 0, 00785 &NewSize, 00786 MEM_COMMIT, 00787 PAGE_READWRITE 00788 ); 00789 if (!NT_SUCCESS( Status )) { 00790 return( Status ); 00791 } 00792 00793 // 00794 // Copy the current process's environment to the allocated memory 00795 // inserting the new value as we do the copy. 00796 // 00797 00798 if (p != NULL) { 00799 Size = (ULONG)(p - (PWSTR)pOld); 00800 RtlMoveMemory( pNew, pOld, Size*sizeof(WCHAR) ); 00801 } 00802 else { 00803 Size = 0; 00804 } 00805 pStart = (PWSTR)pNew + Size; 00806 RtlMoveMemory( pStart, Name->Buffer, Name->Length ); 00807 pStart += Name->Length/sizeof(WCHAR); 00808 *pStart++ = L'='; 00809 RtlMoveMemory( pStart, Value->Buffer, Value->Length ); 00810 pStart += Value->Length/sizeof(WCHAR); 00811 *pStart++ = L'\0'; 00812 if (p != NULL) { 00813 RtlMoveMemory( pStart, p,(ULONG)((pEnd - p)*sizeof(WCHAR)) ); 00814 } 00815 00816 if (ARGUMENT_PRESENT( Environment )) 00817 *Environment = pNew; 00818 else { 00819 NtCurrentPeb()->ProcessParameters->Environment = pNew; 00820 NtCurrentPeb()->EnvironmentUpdateCount += 1; 00821 } 00822 ZwFreeVirtualMemory( NtCurrentProcess(), 00823 &pOld, 00824 &MemoryInformation.RegionSize, 00825 MEM_RELEASE 00826 ); 00827 } 00828 else { 00829 pStart = p + Name->Length/sizeof(WCHAR) + 1 + Value->Length/sizeof(WCHAR) + 1; 00830 RtlMoveMemory( pStart, p,(ULONG)((pEnd - p)*sizeof(WCHAR)) ); 00831 RtlMoveMemory( p, Name->Buffer, Name->Length ); 00832 p += Name->Length/sizeof(WCHAR); 00833 *p++ = L'='; 00834 RtlMoveMemory( p, Value->Buffer, Value->Length ); 00835 p += Value->Length/sizeof(WCHAR); 00836 *p++ = L'\0'; 00837 } 00838 } 00839 } 00840 finally { 00841 // 00842 // Release the Peb lock. 00843 // 00844 00845 if (!ARGUMENT_PRESENT( Environment )) { 00846 RtlReleasePebLock(); 00847 } 00848 00849 // 00850 // If abnormally terminating, assume access violation. 00851 // 00852 00853 if (AbnormalTermination()) { 00854 return (STATUS_ACCESS_VIOLATION); 00855 } 00856 } 00857 00858 // 00859 // Return status. 00860 // 00861 00862 return( Status ); 00863 }


Variable Documentation

UNICODE_STRING RtlpEnvironCacheName
 

Definition at line 246 of file environ.c.

Referenced by RtlQueryEnvironmentVariable_U().

BOOLEAN RtlpEnvironCacheValid
 

Definition at line 245 of file environ.c.

Referenced by RtlQueryEnvironmentVariable_U(), and RtlSetEnvironmentVariable().

UNICODE_STRING RtlpEnvironCacheValue
 

Definition at line 247 of file environ.c.

Referenced by RtlQueryEnvironmentVariable_U().


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