ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

environment.c
Go to the documentation of this file.
00001 /*
00002  *  ReactOS kernel
00003  *  Copyright (C) 2004 ReactOS Team
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License along
00016  *  with this program; if not, write to the Free Software Foundation, Inc.,
00017  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00018  */
00019 /* $Id: environment.c 47194 2010-05-13 20:38:16Z ekohl $
00020  *
00021  * COPYRIGHT:       See COPYING in the top level directory
00022  * PROJECT:         ReactOS system libraries
00023  * FILE:            lib/userenv/environment.c
00024  * PURPOSE:         User environment functions
00025  * PROGRAMMER:      Eric Kohl
00026  */
00027 
00028 #include <precomp.h>
00029 
00030 #define NDEBUG
00031 #include <debug.h>
00032 
00033 
00034 static BOOL
00035 SetUserEnvironmentVariable(LPVOID *Environment,
00036                            LPWSTR lpName,
00037                            LPWSTR lpValue,
00038                            BOOL bExpand)
00039 {
00040     WCHAR ShortName[MAX_PATH];
00041     UNICODE_STRING Name;
00042     UNICODE_STRING SrcValue;
00043     UNICODE_STRING DstValue;
00044     ULONG Length;
00045     NTSTATUS Status;
00046     PVOID Buffer = NULL;
00047 
00048     if (bExpand)
00049     {
00050         RtlInitUnicodeString(&SrcValue,
00051                              lpValue);
00052 
00053         Length = 2 * MAX_PATH * sizeof(WCHAR);
00054 
00055         DstValue.Length = 0;
00056         DstValue.MaximumLength = Length;
00057         DstValue.Buffer = Buffer = LocalAlloc(LPTR,
00058                                               Length);
00059         if (DstValue.Buffer == NULL)
00060         {
00061             DPRINT1("LocalAlloc() failed\n");
00062             return FALSE;
00063         }
00064 
00065         Status = RtlExpandEnvironmentStrings_U((PWSTR)*Environment,
00066                                                &SrcValue,
00067                                                &DstValue,
00068                                                &Length);
00069         if (!NT_SUCCESS(Status))
00070         {
00071             DPRINT1("RtlExpandEnvironmentStrings_U() failed (Status %lx)\n", Status);
00072             DPRINT1("Length %lu\n", Length);
00073             if (Buffer)
00074                 LocalFree(Buffer);
00075             return FALSE;
00076         }
00077     }
00078     else
00079     {
00080         RtlInitUnicodeString(&DstValue,
00081                              lpValue);
00082     }
00083 
00084     if (!_wcsicmp(lpName, L"temp") || !_wcsicmp(lpName, L"tmp"))
00085     {
00086         if (!GetShortPathNameW(DstValue.Buffer, ShortName, MAX_PATH))
00087         {
00088             DPRINT1("GetShortPathNameW() failed for %S (Error %lu)\n", DstValue.Buffer, GetLastError());
00089             if (Buffer)
00090                 LocalFree(Buffer);
00091             return FALSE;
00092         }
00093 
00094         DPRINT("Buffer: %S\n", ShortName);
00095         RtlInitUnicodeString(&DstValue,
00096                              ShortName);
00097     }
00098 
00099     RtlInitUnicodeString(&Name,
00100                          lpName);
00101 
00102     DPRINT("Value: %wZ\n", &DstValue);
00103 
00104     Status = RtlSetEnvironmentVariable((PWSTR*)Environment,
00105                                        &Name,
00106                                        &DstValue);
00107 
00108     if (Buffer)
00109         LocalFree(Buffer);
00110 
00111     if (!NT_SUCCESS(Status))
00112     {
00113         DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status);
00114         return FALSE;
00115     }
00116 
00117     return TRUE;
00118 }
00119 
00120 
00121 static BOOL
00122 AppendUserEnvironmentVariable(LPVOID *Environment,
00123                               LPWSTR lpName,
00124                               LPWSTR lpValue)
00125 {
00126     UNICODE_STRING Name;
00127     UNICODE_STRING Value;
00128     NTSTATUS Status;
00129 
00130     RtlInitUnicodeString(&Name,
00131                          lpName);
00132 
00133     Value.Length = 0;
00134     Value.MaximumLength = 1024 * sizeof(WCHAR);
00135     Value.Buffer = LocalAlloc(LPTR,
00136                               1024 * sizeof(WCHAR));
00137     if (Value.Buffer == NULL)
00138     {
00139         return FALSE;
00140     }
00141     Value.Buffer[0] = UNICODE_NULL;
00142 
00143     Status = RtlQueryEnvironmentVariable_U((PWSTR)*Environment,
00144                                            &Name,
00145                                            &Value);
00146     if (NT_SUCCESS(Status))
00147     {
00148         RtlAppendUnicodeToString(&Value,
00149                                  L";");
00150     }
00151 
00152     RtlAppendUnicodeToString(&Value,
00153                              lpValue);
00154 
00155     Status = RtlSetEnvironmentVariable((PWSTR*)Environment,
00156                                        &Name,
00157                                        &Value);
00158     LocalFree(Value.Buffer);
00159     if (!NT_SUCCESS(Status))
00160     {
00161         DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status);
00162         return FALSE;
00163     }
00164 
00165     return TRUE;
00166 }
00167 
00168 
00169 static HKEY
00170 GetCurrentUserKey(HANDLE hToken)
00171 {
00172     UNICODE_STRING SidString;
00173     HKEY hKey;
00174     LONG Error;
00175 
00176     if (!GetUserSidFromToken(hToken,
00177                              &SidString))
00178     {
00179         DPRINT1("GetUserSidFromToken() failed\n");
00180         return NULL;
00181     }
00182 
00183     Error = RegOpenKeyExW(HKEY_USERS,
00184                           SidString.Buffer,
00185                           0,
00186                           MAXIMUM_ALLOWED,
00187                           &hKey);
00188     if (Error != ERROR_SUCCESS)
00189     {
00190         DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
00191         RtlFreeUnicodeString(&SidString);
00192         SetLastError((DWORD)Error);
00193         return NULL;
00194     }
00195 
00196     RtlFreeUnicodeString(&SidString);
00197 
00198     return hKey;
00199 }
00200 
00201 
00202 static BOOL
00203 SetUserEnvironment(LPVOID *lpEnvironment,
00204                    HKEY hKey,
00205                    LPWSTR lpSubKeyName)
00206 {
00207     HKEY hEnvKey;
00208     DWORD dwValues;
00209     DWORD dwMaxValueNameLength;
00210     DWORD dwMaxValueDataLength;
00211     DWORD dwValueNameLength;
00212     DWORD dwValueDataLength;
00213     DWORD dwType;
00214     DWORD i;
00215     LPWSTR lpValueName;
00216     LPWSTR lpValueData;
00217     LONG Error;
00218 
00219     Error = RegOpenKeyExW(hKey,
00220                           lpSubKeyName,
00221                           0,
00222                           KEY_QUERY_VALUE,
00223                           &hEnvKey);
00224     if (Error != ERROR_SUCCESS)
00225     {
00226         DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
00227         SetLastError((DWORD)Error);
00228         return FALSE;
00229     }
00230 
00231     Error = RegQueryInfoKey(hEnvKey,
00232                             NULL,
00233                             NULL,
00234                             NULL,
00235                             NULL,
00236                             NULL,
00237                             NULL,
00238                             &dwValues,
00239                             &dwMaxValueNameLength,
00240                             &dwMaxValueDataLength,
00241                             NULL,
00242                             NULL);
00243     if (Error != ERROR_SUCCESS)
00244     {
00245         DPRINT1("RegQueryInforKey() failed (Error %ld)\n", Error);
00246         RegCloseKey(hEnvKey);
00247         SetLastError((DWORD)Error);
00248         return FALSE;
00249     }
00250 
00251     if (dwValues == 0)
00252     {
00253         RegCloseKey(hEnvKey);
00254         return TRUE;
00255     }
00256 
00257     /* Allocate buffers */
00258     lpValueName = LocalAlloc(LPTR,
00259                              dwMaxValueNameLength * sizeof(WCHAR));
00260     if (lpValueName == NULL)
00261     {
00262         RegCloseKey(hEnvKey);
00263         return FALSE;
00264     }
00265 
00266     lpValueData = LocalAlloc(LPTR,
00267                              dwMaxValueDataLength);
00268     if (lpValueData == NULL)
00269     {
00270         LocalFree(lpValueName);
00271         RegCloseKey(hEnvKey);
00272         return FALSE;
00273     }
00274 
00275     /* Enumerate values */
00276     for (i = 0; i < dwValues; i++)
00277     {
00278         dwValueNameLength = dwMaxValueNameLength;
00279         dwValueDataLength = dwMaxValueDataLength;
00280         RegEnumValueW(hEnvKey,
00281                       i,
00282                       lpValueName,
00283                       &dwValueNameLength,
00284                       NULL,
00285                       &dwType,
00286                       (LPBYTE)lpValueData,
00287                       &dwValueDataLength);
00288 
00289         if (!_wcsicmp (lpValueName, L"path"))
00290         {
00291             /* Append 'Path' environment variable */
00292             AppendUserEnvironmentVariable(lpEnvironment,
00293                                           lpValueName,
00294                                           lpValueData);
00295         }
00296         else
00297         {
00298             /* Set environment variable */
00299             SetUserEnvironmentVariable(lpEnvironment,
00300                                        lpValueName,
00301                                        lpValueData,
00302                                        (dwType == REG_EXPAND_SZ));
00303         }
00304     }
00305 
00306     LocalFree(lpValueData);
00307     LocalFree(lpValueName);
00308     RegCloseKey(hEnvKey);
00309 
00310     return TRUE;
00311 }
00312 
00313 
00314 BOOL WINAPI
00315 CreateEnvironmentBlock(LPVOID *lpEnvironment,
00316                        HANDLE hToken,
00317                        BOOL bInherit)
00318 {
00319     WCHAR Buffer[MAX_PATH];
00320     WCHAR szValue[1024];
00321     DWORD Length;
00322     DWORD dwType;
00323     HKEY hKey;
00324     HKEY hKeyUser;
00325     NTSTATUS Status;
00326     LONG lError;
00327 
00328     DPRINT("CreateEnvironmentBlock() called\n");
00329 
00330     if (lpEnvironment == NULL)
00331     {
00332         SetLastError(ERROR_INVALID_PARAMETER);
00333         return FALSE;
00334     }
00335 
00336     Status = RtlCreateEnvironment((BOOLEAN)bInherit,
00337                                   (PWSTR*)lpEnvironment);
00338     if (!NT_SUCCESS (Status))
00339     {
00340         DPRINT1("RtlCreateEnvironment() failed (Status %lx)\n", Status);
00341         SetLastError(RtlNtStatusToDosError(Status));
00342         return FALSE;
00343     }
00344 
00345     /* Set 'COMPUTERNAME' variable */
00346     Length = MAX_PATH;
00347     if (GetComputerNameW(Buffer,
00348                          &Length))
00349     {
00350         SetUserEnvironmentVariable(lpEnvironment,
00351                                    L"COMPUTERNAME",
00352                                    Buffer,
00353                                    FALSE);
00354     }
00355 
00356     /* Set 'ALLUSERSPROFILE' variable */
00357     Length = MAX_PATH;
00358     if (GetAllUsersProfileDirectoryW(Buffer,
00359                                      &Length))
00360     {
00361         SetUserEnvironmentVariable(lpEnvironment,
00362                                    L"ALLUSERSPROFILE",
00363                                    Buffer,
00364                                    FALSE);
00365     }
00366 
00367     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00368                            L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
00369                            0,
00370                            KEY_READ,
00371                            &hKey);
00372     if (lError == ERROR_SUCCESS)
00373     {
00374         Length = 1024 * sizeof(WCHAR);
00375         lError = RegQueryValueExW(hKey,
00376                                   L"ProgramFilesDir",
00377                                   NULL,
00378                                   &dwType,
00379                                   (LPBYTE)szValue,
00380                                   &Length);
00381         if (lError == ERROR_SUCCESS)
00382         {
00383             SetUserEnvironmentVariable(lpEnvironment,
00384                                        L"ProgramFiles",
00385                                        szValue,
00386                                        FALSE);
00387         }
00388 
00389         Length = 1024 * sizeof(WCHAR);
00390         lError = RegQueryValueExW(hKey,
00391                                   L"CommonFilesDir",
00392                                   NULL,
00393                                   &dwType,
00394                                   (LPBYTE)szValue,
00395                                   &Length);
00396         if (lError == ERROR_SUCCESS)
00397         {
00398             SetUserEnvironmentVariable(lpEnvironment,
00399                                        L"CommonProgramFiles",
00400                                        szValue,
00401                                        FALSE);
00402         }
00403 
00404         RegCloseKey(hKey);
00405     }
00406 
00407     if (hToken == NULL)
00408         return TRUE;
00409 
00410     hKeyUser = GetCurrentUserKey(hToken);
00411     if (hKeyUser == NULL)
00412     {
00413         DPRINT1("GetCurrentUserKey() failed\n");
00414         RtlDestroyEnvironment(*lpEnvironment);
00415         return FALSE;
00416     }
00417 
00418     /* Set 'USERPROFILE' variable */
00419     Length = MAX_PATH;
00420     if (GetUserProfileDirectoryW(hToken,
00421                                  Buffer,
00422                                  &Length))
00423     {
00424         SetUserEnvironmentVariable(lpEnvironment,
00425                                    L"USERPROFILE",
00426                                    Buffer,
00427                                    FALSE);
00428     }
00429 
00430     /* FIXME: Set 'USERDOMAIN' variable */
00431 
00432     Length = MAX_PATH;
00433     if (GetUserNameW(Buffer,
00434                      &Length))
00435     {
00436         SetUserEnvironmentVariable(lpEnvironment,
00437                                    L"USERNAME",
00438                                    Buffer,
00439                                    FALSE);
00440     }
00441 
00442     /* Set user environment variables */
00443     SetUserEnvironment(lpEnvironment,
00444                        hKeyUser,
00445                        L"Environment");
00446 
00447     /* Set user volatile environment variables */
00448     SetUserEnvironment(lpEnvironment,
00449                        hKeyUser,
00450                        L"Volatile Environment");
00451 
00452     RegCloseKey(hKeyUser);
00453 
00454     return TRUE;
00455 }
00456 
00457 
00458 BOOL WINAPI
00459 DestroyEnvironmentBlock(LPVOID lpEnvironment)
00460 {
00461     DPRINT("DestroyEnvironmentBlock() called\n");
00462 
00463     if (lpEnvironment == NULL)
00464     {
00465         SetLastError(ERROR_INVALID_PARAMETER);
00466         return FALSE;
00467     }
00468 
00469     RtlDestroyEnvironment(lpEnvironment);
00470 
00471     return TRUE;
00472 }
00473 
00474 
00475 BOOL WINAPI
00476 ExpandEnvironmentStringsForUserW(IN HANDLE hToken,
00477                                  IN LPCWSTR lpSrc,
00478                                  OUT LPWSTR lpDest,
00479                                  IN DWORD dwSize)
00480 {
00481     PVOID lpEnvironment;
00482     BOOL Ret = FALSE;
00483 
00484     if (lpSrc == NULL || lpDest == NULL || dwSize == 0)
00485     {
00486         SetLastError(ERROR_INVALID_PARAMETER);
00487         return FALSE;
00488     }
00489 
00490     if (CreateEnvironmentBlock(&lpEnvironment,
00491                                hToken,
00492                                FALSE))
00493     {
00494         UNICODE_STRING SrcU, DestU;
00495         NTSTATUS Status;
00496 
00497         /* initialize the strings */
00498         RtlInitUnicodeString(&SrcU,
00499                              lpSrc);
00500         DestU.Length = 0;
00501         DestU.MaximumLength = dwSize * sizeof(WCHAR);
00502         DestU.Buffer = lpDest;
00503 
00504         /* expand the strings */
00505         Status = RtlExpandEnvironmentStrings_U((PWSTR)lpEnvironment,
00506                                                &SrcU,
00507                                                &DestU,
00508                                                NULL);
00509 
00510         DestroyEnvironmentBlock(lpEnvironment);
00511 
00512         if (NT_SUCCESS(Status))
00513         {
00514             Ret = TRUE;
00515         }
00516         else
00517         {
00518             SetLastError(RtlNtStatusToDosError(Status));
00519         }
00520     }
00521 
00522     return Ret;
00523 }
00524 
00525 
00526 BOOL WINAPI
00527 ExpandEnvironmentStringsForUserA(IN HANDLE hToken,
00528                                  IN LPCSTR lpSrc,
00529                                  OUT LPSTR lpDest,
00530                                  IN DWORD dwSize)
00531 {
00532     DWORD dwSrcLen;
00533     LPWSTR lpSrcW = NULL, lpDestW = NULL;
00534     BOOL Ret = FALSE;
00535 
00536     if (lpSrc == NULL || lpDest == NULL || dwSize == 0)
00537     {
00538         SetLastError(ERROR_INVALID_PARAMETER);
00539         return FALSE;
00540     }
00541 
00542     dwSrcLen = strlen(lpSrc);
00543     lpSrcW = (LPWSTR)GlobalAlloc(GMEM_FIXED,
00544                                  (dwSrcLen + 1) * sizeof(WCHAR));
00545     if (lpSrcW == NULL ||
00546         MultiByteToWideChar(CP_ACP,
00547                             0,
00548                             lpSrc,
00549                             -1,
00550                             lpSrcW,
00551                             dwSrcLen + 1) == 0)
00552     {
00553         goto Cleanup;
00554     }
00555 
00556     lpDestW = (LPWSTR)GlobalAlloc(GMEM_FIXED,
00557                                   dwSize * sizeof(WCHAR));
00558     if (lpDestW == NULL)
00559     {
00560         goto Cleanup;
00561     }
00562 
00563     Ret = ExpandEnvironmentStringsForUserW(hToken,
00564                                            lpSrcW,
00565                                            lpDestW,
00566                                            dwSize);
00567     if (Ret)
00568     {
00569         if (WideCharToMultiByte(CP_ACP,
00570                                 0,
00571                                 lpDestW,
00572                                 -1,
00573                                 lpDest,
00574                                 dwSize,
00575                                 NULL,
00576                                 NULL) == 0)
00577         {
00578             Ret = FALSE;
00579         }
00580     }
00581 
00582 Cleanup:
00583     if (lpSrcW != NULL)
00584     {
00585         GlobalFree((HGLOBAL)lpSrcW);
00586     }
00587 
00588     if (lpDestW != NULL)
00589     {
00590         GlobalFree((HGLOBAL)lpDestW);
00591     }
00592 
00593     return Ret;
00594 }
00595 
00596 /* EOF */

Generated on Sun May 27 2012 04:18:59 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.