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

profile.c
Go to the documentation of this file.
00001 /*
00002  *  ReactOS kernel
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00017  */
00018 /*
00019  * COPYRIGHT:       See COPYING in the top level directory
00020  * PROJECT:         ReactOS system libraries
00021  * FILE:            lib/userenv/profile.c
00022  * PURPOSE:         User profile code
00023  * PROGRAMMERS:     Eric Kohl
00024  *                  Hervé Poussineau
00025  */
00026 
00027 #include <precomp.h>
00028 
00029 #define NDEBUG
00030 #include <debug.h>
00031 
00032 
00033 /* FUNCTIONS ***************************************************************/
00034 
00035 BOOL
00036 AppendSystemPostfix(LPWSTR lpName,
00037                     DWORD dwMaxLength)
00038 {
00039     WCHAR szSystemRoot[MAX_PATH];
00040     LPWSTR lpszPostfix;
00041     LPWSTR lpszPtr;
00042 
00043     /* Build profile name postfix */
00044     if (!ExpandEnvironmentStringsW(L"%SystemRoot%",
00045                                    szSystemRoot,
00046                                    MAX_PATH))
00047     {
00048         DPRINT1("Error: %lu\n", GetLastError());
00049         return FALSE;
00050     }
00051 
00052     _wcsupr(szSystemRoot);
00053 
00054     /* Get name postfix */
00055     szSystemRoot[2] = L'.';
00056     lpszPostfix = &szSystemRoot[2];
00057     lpszPtr = lpszPostfix;
00058     while (*lpszPtr != (WCHAR)0)
00059     {
00060         if (*lpszPtr == L'\\')
00061             *lpszPtr = '_';
00062         lpszPtr++;
00063     }
00064 
00065     if (wcslen(lpName) + wcslen(lpszPostfix) + 1 >= dwMaxLength)
00066     {
00067         DPRINT1("Error: buffer overflow\n");
00068         SetLastError(ERROR_BUFFER_OVERFLOW);
00069         return FALSE;
00070     }
00071 
00072     wcscat(lpName, lpszPostfix);
00073 
00074     return TRUE;
00075 }
00076 
00077 
00078 BOOL
00079 WINAPI
00080 CreateUserProfileA(PSID Sid,
00081                    LPCSTR lpUserName)
00082 {
00083     UNICODE_STRING UserName;
00084     BOOL bResult;
00085     NTSTATUS Status;
00086 
00087     Status = RtlCreateUnicodeStringFromAsciiz(&UserName,
00088                                               (LPSTR)lpUserName);
00089     if (!NT_SUCCESS(Status))
00090     {
00091         SetLastError(RtlNtStatusToDosError(Status));
00092         return FALSE;
00093     }
00094 
00095     bResult = CreateUserProfileW(Sid, UserName.Buffer);
00096 
00097     RtlFreeUnicodeString(&UserName);
00098 
00099     return bResult;
00100 }
00101 
00102 
00103 static
00104 BOOL
00105 AcquireRemoveRestorePrivilege(IN BOOL bAcquire)
00106 {
00107     HANDLE Process;
00108     HANDLE Token;
00109     PTOKEN_PRIVILEGES TokenPriv;
00110     BOOL bRet;
00111 
00112     DPRINT("AcquireRemoveRestorePrivilege(%d)\n", bAcquire);
00113 
00114     Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
00115     if (!Process)
00116     {
00117         DPRINT1("OpenProcess() failed with error %lu\n", GetLastError());
00118         return FALSE;
00119     }
00120     bRet = OpenProcessToken(Process, TOKEN_ADJUST_PRIVILEGES, &Token);
00121     CloseHandle(Process);
00122     if (!bRet)
00123     {
00124         DPRINT1("OpenProcessToken() failed with error %lu\n", GetLastError());
00125         return FALSE;
00126     }
00127     TokenPriv = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges) + sizeof(LUID_AND_ATTRIBUTES));
00128     if (!TokenPriv)
00129     {
00130         DPRINT1("Failed to allocate mem for token privileges\n");
00131         CloseHandle(Token);
00132         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00133         return FALSE;
00134     }
00135     TokenPriv->PrivilegeCount = 1;
00136     TokenPriv->Privileges[0].Attributes = bAcquire ? SE_PRIVILEGE_ENABLED : 0;
00137     if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &TokenPriv->Privileges[0].Luid))
00138     {
00139         DPRINT1("LookupPrivilegeValue() failed with error %lu\n", GetLastError());
00140         HeapFree(GetProcessHeap(), 0, TokenPriv);
00141         CloseHandle(Token);
00142         return FALSE;
00143     }
00144     bRet = AdjustTokenPrivileges(
00145         Token,
00146         FALSE,
00147         TokenPriv,
00148         0,
00149         NULL,
00150         NULL);
00151     HeapFree(GetProcessHeap(), 0, TokenPriv);
00152     CloseHandle(Token);
00153 
00154     if (!bRet)
00155     {
00156         DPRINT1("AdjustTokenPrivileges() failed with error %lu\n", GetLastError());
00157         return FALSE;
00158     }
00159 
00160     return TRUE;
00161 }
00162 
00163 
00164 BOOL
00165 WINAPI
00166 CreateUserProfileW(PSID Sid,
00167                    LPCWSTR lpUserName)
00168 {
00169     WCHAR szRawProfilesPath[MAX_PATH];
00170     WCHAR szProfilesPath[MAX_PATH];
00171     WCHAR szUserProfilePath[MAX_PATH];
00172     WCHAR szDefaultUserPath[MAX_PATH];
00173     WCHAR szUserProfileName[MAX_PATH];
00174     WCHAR szBuffer[MAX_PATH];
00175     LPWSTR SidString;
00176     DWORD dwLength;
00177     DWORD dwDisposition;
00178     UINT i;
00179     HKEY hKey;
00180     LONG Error;
00181 
00182     DPRINT("CreateUserProfileW() called\n");
00183 
00184     Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00185                           L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
00186                           0,
00187                           KEY_QUERY_VALUE,
00188                           &hKey);
00189     if (Error != ERROR_SUCCESS)
00190     {
00191         DPRINT1("Error: %lu\n", Error);
00192         SetLastError((DWORD)Error);
00193         return FALSE;
00194     }
00195 
00196     /* Get profiles path */
00197     dwLength = MAX_PATH * sizeof(WCHAR);
00198     Error = RegQueryValueExW(hKey,
00199                              L"ProfilesDirectory",
00200                              NULL,
00201                              NULL,
00202                              (LPBYTE)szRawProfilesPath,
00203                              &dwLength);
00204     if (Error != ERROR_SUCCESS)
00205     {
00206         DPRINT1("Error: %lu\n", Error);
00207         RegCloseKey(hKey);
00208         SetLastError((DWORD)Error);
00209         return FALSE;
00210     }
00211 
00212     /* Expand it */
00213     if (!ExpandEnvironmentStringsW(szRawProfilesPath,
00214                                    szProfilesPath,
00215                                    MAX_PATH))
00216     {
00217         DPRINT1("Error: %lu\n", GetLastError());
00218         RegCloseKey(hKey);
00219         return FALSE;
00220     }
00221 
00222     /* create the profiles directory if it does not yet exist */
00223     if (!CreateDirectoryW(szProfilesPath, NULL))
00224     {
00225         if (GetLastError() != ERROR_ALREADY_EXISTS)
00226         {
00227             DPRINT1("Error: %lu\n", GetLastError());
00228             return FALSE;
00229         }
00230     }
00231 
00232     /* Get default user path */
00233     dwLength = MAX_PATH * sizeof(WCHAR);
00234     Error = RegQueryValueExW(hKey,
00235                              L"DefaultUserProfile",
00236                              NULL,
00237                              NULL,
00238                              (LPBYTE)szBuffer,
00239                              &dwLength);
00240     if (Error != ERROR_SUCCESS)
00241     {
00242         DPRINT1("Error: %lu\n", Error);
00243         RegCloseKey(hKey);
00244         SetLastError((DWORD)Error);
00245         return FALSE;
00246     }
00247 
00248     RegCloseKey (hKey);
00249 
00250     wcscpy(szUserProfileName, lpUserName);
00251 
00252     wcscpy(szUserProfilePath, szProfilesPath);
00253     wcscat(szUserProfilePath, L"\\");
00254     wcscat(szUserProfilePath, szUserProfileName);
00255 
00256     wcscpy(szDefaultUserPath, szProfilesPath);
00257     wcscat(szDefaultUserPath, L"\\");
00258     wcscat(szDefaultUserPath, szBuffer);
00259 
00260     /* Create user profile directory */
00261     if (!CreateDirectoryW(szUserProfilePath, NULL))
00262     {
00263         if (GetLastError() != ERROR_ALREADY_EXISTS)
00264         {
00265             DPRINT1("Error: %lu\n", GetLastError());
00266             return FALSE;
00267         }
00268 
00269         for (i = 0; i < 1000; i++)
00270         {
00271             swprintf(szUserProfileName, L"%s.%03u", lpUserName, i);
00272 
00273             wcscpy(szUserProfilePath, szProfilesPath);
00274             wcscat(szUserProfilePath, L"\\");
00275             wcscat(szUserProfilePath, szUserProfileName);
00276 
00277             if (CreateDirectoryW(szUserProfilePath, NULL))
00278                 break;
00279 
00280             if (GetLastError() != ERROR_ALREADY_EXISTS)
00281             {
00282                 DPRINT1("Error: %lu\n", GetLastError());
00283                 return FALSE;
00284             }
00285         }
00286     }
00287 
00288     /* Copy default user directory */
00289     if (!CopyDirectory(szUserProfilePath, szDefaultUserPath))
00290     {
00291         DPRINT1("Error: %lu\n", GetLastError());
00292         return FALSE;
00293     }
00294 
00295     /* Add profile to profile list */
00296     if (!ConvertSidToStringSidW(Sid,
00297                                 &SidString))
00298     {
00299         DPRINT1("Error: %lu\n", GetLastError());
00300         return FALSE;
00301     }
00302 
00303     wcscpy(szBuffer,
00304            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
00305     wcscat(szBuffer, SidString);
00306 
00307     /* Create user profile key */
00308     Error = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
00309                             szBuffer,
00310                             0,
00311                             NULL,
00312                             REG_OPTION_NON_VOLATILE,
00313                             KEY_ALL_ACCESS,
00314                             NULL,
00315                             &hKey,
00316                             &dwDisposition);
00317     if (Error != ERROR_SUCCESS)
00318     {
00319         DPRINT1("Error: %lu\n", Error);
00320         LocalFree((HLOCAL)SidString);
00321         SetLastError((DWORD)Error);
00322         return FALSE;
00323     }
00324 
00325     /* Create non-expanded user profile path */
00326     wcscpy(szBuffer, szRawProfilesPath);
00327     wcscat(szBuffer, L"\\");
00328     wcscat(szBuffer, szUserProfileName);
00329 
00330     /* Set 'ProfileImagePath' value (non-expanded) */
00331     Error = RegSetValueExW(hKey,
00332                            L"ProfileImagePath",
00333                            0,
00334                            REG_EXPAND_SZ,
00335                            (LPBYTE)szBuffer,
00336                            (wcslen (szBuffer) + 1) * sizeof(WCHAR));
00337     if (Error != ERROR_SUCCESS)
00338     {
00339         DPRINT1("Error: %lu\n", Error);
00340         LocalFree((HLOCAL)SidString);
00341         RegCloseKey(hKey);
00342         SetLastError((DWORD)Error);
00343         return FALSE;
00344     }
00345 
00346     /* Set 'Sid' value */
00347     Error = RegSetValueExW(hKey,
00348                            L"Sid",
00349                            0,
00350                            REG_BINARY,
00351                            Sid,
00352                            GetLengthSid(Sid));
00353     if (Error != ERROR_SUCCESS)
00354     {
00355         DPRINT1("Error: %lu\n", Error);
00356         LocalFree((HLOCAL)SidString);
00357         RegCloseKey(hKey);
00358         SetLastError((DWORD)Error);
00359         return FALSE;
00360     }
00361 
00362     RegCloseKey (hKey);
00363 
00364     /* Create user hive name */
00365     wcscpy(szBuffer, szUserProfilePath);
00366     wcscat(szBuffer, L"\\ntuser.dat");
00367 
00368     /* Acquire restore privilege */
00369     if (!AcquireRemoveRestorePrivilege(TRUE))
00370     {
00371         DPRINT1("Error: %lu\n", Error);
00372         LocalFree((HLOCAL)SidString);
00373         return FALSE;
00374     }
00375 
00376     /* Create new user hive */
00377     Error = RegLoadKeyW(HKEY_USERS,
00378                         SidString,
00379                         szBuffer);
00380     AcquireRemoveRestorePrivilege(FALSE);
00381     if (Error != ERROR_SUCCESS)
00382     {
00383         DPRINT1("Error: %lu\n", Error);
00384         LocalFree((HLOCAL)SidString);
00385         SetLastError((DWORD)Error);
00386         return FALSE;
00387     }
00388 
00389     /* Initialize user hive */
00390     if (!CreateUserHive(SidString, szUserProfilePath))
00391     {
00392         DPRINT1("Error: %lu\n", GetLastError());
00393         LocalFree((HLOCAL)SidString);
00394         return FALSE;
00395     }
00396 
00397     RegUnLoadKeyW(HKEY_USERS, SidString);
00398 
00399     LocalFree((HLOCAL)SidString);
00400 
00401     DPRINT("CreateUserProfileW() done\n");
00402 
00403     return TRUE;
00404 }
00405 
00406 
00407 BOOL
00408 WINAPI
00409 GetAllUsersProfileDirectoryA(LPSTR lpProfileDir,
00410                              LPDWORD lpcchSize)
00411 {
00412     LPWSTR lpBuffer;
00413     BOOL bResult;
00414 
00415     lpBuffer = GlobalAlloc(GMEM_FIXED,
00416                            *lpcchSize * sizeof(WCHAR));
00417     if (lpBuffer == NULL)
00418         return FALSE;
00419 
00420     bResult = GetAllUsersProfileDirectoryW(lpBuffer,
00421                                            lpcchSize);
00422     if (bResult)
00423     {
00424         WideCharToMultiByte(CP_ACP,
00425                             0,
00426                             lpBuffer,
00427                             -1,
00428                             lpProfileDir,
00429                             *lpcchSize,
00430                             NULL,
00431                             NULL);
00432     }
00433 
00434     GlobalFree(lpBuffer);
00435 
00436     return bResult;
00437 }
00438 
00439 
00440 BOOL
00441 WINAPI
00442 GetAllUsersProfileDirectoryW(LPWSTR lpProfileDir,
00443                              LPDWORD lpcchSize)
00444 {
00445     WCHAR szProfilePath[MAX_PATH];
00446     WCHAR szBuffer[MAX_PATH];
00447     DWORD dwLength;
00448     HKEY hKey;
00449     LONG Error;
00450 
00451     Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00452                           L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
00453                           0,
00454                           KEY_QUERY_VALUE,
00455                           &hKey);
00456     if (Error != ERROR_SUCCESS)
00457     {
00458         DPRINT1("Error: %lu\n", Error);
00459         SetLastError((DWORD)Error);
00460         return FALSE;
00461     }
00462 
00463     /* Get profiles path */
00464     dwLength = sizeof(szBuffer);
00465     Error = RegQueryValueExW(hKey,
00466                              L"ProfilesDirectory",
00467                              NULL,
00468                              NULL,
00469                              (LPBYTE)szBuffer,
00470                              &dwLength);
00471     if (Error != ERROR_SUCCESS)
00472     {
00473         DPRINT1("Error: %lu\n", Error);
00474         RegCloseKey(hKey);
00475         SetLastError((DWORD)Error);
00476         return FALSE;
00477     }
00478 
00479     /* Expand it */
00480     if (!ExpandEnvironmentStringsW(szBuffer,
00481                                    szProfilePath,
00482                                    MAX_PATH))
00483     {
00484         DPRINT1("Error: %lu\n", GetLastError());
00485         RegCloseKey (hKey);
00486         return FALSE;
00487     }
00488 
00489     /* Get 'AllUsersProfile' name */
00490     dwLength = sizeof(szBuffer);
00491     Error = RegQueryValueExW(hKey,
00492                              L"AllUsersProfile",
00493                              NULL,
00494                              NULL,
00495                              (LPBYTE)szBuffer,
00496                              &dwLength);
00497     if (Error != ERROR_SUCCESS)
00498     {
00499         DPRINT1("Error: %lu\n", Error);
00500         RegCloseKey(hKey);
00501         SetLastError((DWORD)Error);
00502         return FALSE;
00503     }
00504 
00505     RegCloseKey (hKey);
00506 
00507     wcscat(szProfilePath, L"\\");
00508     wcscat(szProfilePath, szBuffer);
00509 
00510     dwLength = wcslen(szProfilePath) + 1;
00511     if (lpProfileDir != NULL)
00512     {
00513         if (*lpcchSize < dwLength)
00514         {
00515             *lpcchSize = dwLength;
00516             SetLastError(ERROR_INSUFFICIENT_BUFFER);
00517             return FALSE;
00518         }
00519 
00520         wcscpy(lpProfileDir, szProfilePath);
00521     }
00522 
00523     *lpcchSize = dwLength;
00524 
00525     return TRUE;
00526 }
00527 
00528 
00529 BOOL
00530 WINAPI
00531 GetDefaultUserProfileDirectoryA(LPSTR lpProfileDir,
00532                                 LPDWORD lpcchSize)
00533 {
00534     LPWSTR lpBuffer;
00535     BOOL bResult;
00536 
00537     lpBuffer = GlobalAlloc(GMEM_FIXED,
00538                            *lpcchSize * sizeof(WCHAR));
00539     if (lpBuffer == NULL)
00540         return FALSE;
00541 
00542     bResult = GetDefaultUserProfileDirectoryW(lpBuffer,
00543                                               lpcchSize);
00544     if (bResult)
00545     {
00546         WideCharToMultiByte(CP_ACP,
00547                             0,
00548                             lpBuffer,
00549                             -1,
00550                             lpProfileDir,
00551                             *lpcchSize,
00552                             NULL,
00553                             NULL);
00554     }
00555 
00556     GlobalFree(lpBuffer);
00557 
00558     return bResult;
00559 }
00560 
00561 
00562 BOOL
00563 WINAPI
00564 GetDefaultUserProfileDirectoryW(LPWSTR lpProfileDir,
00565                                 LPDWORD lpcchSize)
00566 {
00567     WCHAR szProfilePath[MAX_PATH];
00568     WCHAR szBuffer[MAX_PATH];
00569     DWORD dwLength;
00570     HKEY hKey;
00571     LONG Error;
00572 
00573     Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00574                           L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
00575                           0,
00576                           KEY_QUERY_VALUE,
00577                           &hKey);
00578     if (Error != ERROR_SUCCESS)
00579     {
00580         DPRINT1("Error: %lu\n", Error);
00581         SetLastError((DWORD)Error);
00582         return FALSE;
00583     }
00584 
00585     /* Get profiles path */
00586     dwLength = sizeof(szBuffer);
00587     Error = RegQueryValueExW(hKey,
00588                              L"ProfilesDirectory",
00589                              NULL,
00590                              NULL,
00591                              (LPBYTE)szBuffer,
00592                              &dwLength);
00593     if (Error != ERROR_SUCCESS)
00594     {
00595         DPRINT1("Error: %lu\n", Error);
00596         RegCloseKey(hKey);
00597         SetLastError((DWORD)Error);
00598         return FALSE;
00599     }
00600 
00601     /* Expand it */
00602     if (!ExpandEnvironmentStringsW(szBuffer,
00603                                    szProfilePath,
00604                                    MAX_PATH))
00605     {
00606         DPRINT1("Error: %lu\n", GetLastError());
00607         RegCloseKey(hKey);
00608         return FALSE;
00609     }
00610 
00611     /* Get 'DefaultUserProfile' name */
00612     dwLength = sizeof(szBuffer);
00613     Error = RegQueryValueExW(hKey,
00614                              L"DefaultUserProfile",
00615                              NULL,
00616                              NULL,
00617                              (LPBYTE)szBuffer,
00618                              &dwLength);
00619     if (Error != ERROR_SUCCESS)
00620     {
00621         DPRINT1("Error: %lu\n", Error);
00622         RegCloseKey(hKey);
00623         SetLastError((DWORD)Error);
00624         return FALSE;
00625     }
00626 
00627     RegCloseKey(hKey);
00628 
00629     wcscat(szProfilePath, L"\\");
00630     wcscat(szProfilePath, szBuffer);
00631 
00632     dwLength = wcslen(szProfilePath) + 1;
00633     if (lpProfileDir != NULL)
00634     {
00635         if (*lpcchSize < dwLength)
00636         {
00637             *lpcchSize = dwLength;
00638             SetLastError(ERROR_INSUFFICIENT_BUFFER);
00639             return FALSE;
00640         }
00641 
00642         wcscpy(lpProfileDir, szProfilePath);
00643     }
00644 
00645     *lpcchSize = dwLength;
00646 
00647     return TRUE;
00648 }
00649 
00650 
00651 BOOL
00652 WINAPI
00653 GetProfilesDirectoryA(LPSTR lpProfileDir,
00654                       LPDWORD lpcchSize)
00655 {
00656     LPWSTR lpBuffer;
00657     BOOL bResult;
00658 
00659     lpBuffer = GlobalAlloc(GMEM_FIXED,
00660                            *lpcchSize * sizeof(WCHAR));
00661     if (lpBuffer == NULL)
00662         return FALSE;
00663 
00664     bResult = GetProfilesDirectoryW(lpBuffer,
00665                                     lpcchSize);
00666     if (bResult)
00667     {
00668         WideCharToMultiByte(CP_ACP,
00669                             0,
00670                             lpBuffer,
00671                             -1,
00672                             lpProfileDir,
00673                             *lpcchSize,
00674                             NULL,
00675                             NULL);
00676     }
00677 
00678     GlobalFree(lpBuffer);
00679 
00680     return bResult;
00681 }
00682 
00683 
00684 BOOL
00685 WINAPI
00686 GetProfilesDirectoryW(LPWSTR lpProfilesDir,
00687                       LPDWORD lpcchSize)
00688 {
00689     WCHAR szProfilesPath[MAX_PATH];
00690     WCHAR szBuffer[MAX_PATH];
00691     DWORD dwLength;
00692     HKEY hKey;
00693     LONG Error;
00694 
00695     Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00696                           L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
00697                           0,
00698                           KEY_QUERY_VALUE,
00699                           &hKey);
00700     if (Error != ERROR_SUCCESS)
00701     {
00702         DPRINT1("Error: %lu\n", Error);
00703         SetLastError((DWORD)Error);
00704         return FALSE;
00705     }
00706 
00707     /* Get profiles path */
00708     dwLength = sizeof(szBuffer);
00709     Error = RegQueryValueExW(hKey,
00710                              L"ProfilesDirectory",
00711                              NULL,
00712                              NULL,
00713                              (LPBYTE)szBuffer,
00714                              &dwLength);
00715     if (Error != ERROR_SUCCESS)
00716     {
00717         DPRINT1("Error: %lu\n", Error);
00718         RegCloseKey(hKey);
00719         SetLastError((DWORD)Error);
00720         return FALSE;
00721     }
00722 
00723     RegCloseKey(hKey);
00724 
00725     /* Expand it */
00726     if (!ExpandEnvironmentStringsW(szBuffer,
00727                                    szProfilesPath,
00728                                    MAX_PATH))
00729     {
00730         DPRINT1("Error: %lu\n", GetLastError());
00731         return FALSE;
00732     }
00733 
00734     dwLength = wcslen (szProfilesPath) + 1;
00735     if (lpProfilesDir != NULL)
00736     {
00737         if (*lpcchSize < dwLength)
00738         {
00739             *lpcchSize = dwLength;
00740             SetLastError(ERROR_INSUFFICIENT_BUFFER);
00741             return FALSE;
00742         }
00743 
00744         wcscpy(lpProfilesDir, szProfilesPath);
00745     }
00746 
00747     *lpcchSize = dwLength;
00748 
00749     return TRUE;
00750 }
00751 
00752 
00753 BOOL
00754 WINAPI
00755 GetUserProfileDirectoryA(HANDLE hToken,
00756                          LPSTR lpProfileDir,
00757                          LPDWORD lpcchSize)
00758 {
00759     LPWSTR lpBuffer;
00760     BOOL bResult;
00761 
00762     lpBuffer = GlobalAlloc(GMEM_FIXED,
00763                            *lpcchSize * sizeof(WCHAR));
00764     if (lpBuffer == NULL)
00765         return FALSE;
00766 
00767     bResult = GetUserProfileDirectoryW(hToken,
00768                                        lpBuffer,
00769                                        lpcchSize);
00770     if (bResult)
00771     {
00772         WideCharToMultiByte(CP_ACP,
00773                             0,
00774                             lpBuffer,
00775                             -1,
00776                             lpProfileDir,
00777                             *lpcchSize,
00778                             NULL,
00779                             NULL);
00780     }
00781 
00782     GlobalFree(lpBuffer);
00783 
00784     return bResult;
00785 }
00786 
00787 
00788 BOOL
00789 WINAPI
00790 GetUserProfileDirectoryW(HANDLE hToken,
00791                          LPWSTR lpProfileDir,
00792                          LPDWORD lpcchSize)
00793 {
00794     UNICODE_STRING SidString;
00795     WCHAR szKeyName[MAX_PATH];
00796     WCHAR szRawImagePath[MAX_PATH];
00797     WCHAR szImagePath[MAX_PATH];
00798     DWORD dwLength;
00799     HKEY hKey;
00800     LONG Error;
00801 
00802     if (!GetUserSidFromToken(hToken,
00803                              &SidString))
00804     {
00805         DPRINT1("GetUserSidFromToken() failed\n");
00806         return FALSE;
00807     }
00808 
00809     DPRINT("SidString: '%wZ'\n", &SidString);
00810 
00811     wcscpy(szKeyName,
00812            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
00813     wcscat(szKeyName,
00814            SidString.Buffer);
00815 
00816     RtlFreeUnicodeString(&SidString);
00817 
00818     DPRINT("KeyName: '%S'\n", szKeyName);
00819 
00820     Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00821                           szKeyName,
00822                           0,
00823                           KEY_QUERY_VALUE,
00824                           &hKey);
00825     if (Error != ERROR_SUCCESS)
00826     {
00827         DPRINT1("Error: %lu\n", Error);
00828         SetLastError((DWORD)Error);
00829         return FALSE;
00830     }
00831 
00832     dwLength = sizeof(szRawImagePath);
00833     Error = RegQueryValueExW(hKey,
00834                              L"ProfileImagePath",
00835                              NULL,
00836                              NULL,
00837                              (LPBYTE)szRawImagePath,
00838                              &dwLength);
00839     if (Error != ERROR_SUCCESS)
00840     {
00841         DPRINT1("Error: %lu\n", Error);
00842         RegCloseKey(hKey);
00843         SetLastError((DWORD)Error);
00844         return FALSE;
00845     }
00846 
00847     RegCloseKey(hKey);
00848 
00849     DPRINT("RawImagePath: '%S'\n", szRawImagePath);
00850 
00851     /* Expand it */
00852     if (!ExpandEnvironmentStringsW(szRawImagePath,
00853                                    szImagePath,
00854                                    MAX_PATH))
00855     {
00856         DPRINT1 ("Error: %lu\n", GetLastError());
00857         return FALSE;
00858     }
00859 
00860     DPRINT("ImagePath: '%S'\n", szImagePath);
00861 
00862     dwLength = wcslen (szImagePath) + 1;
00863     if (*lpcchSize < dwLength)
00864     {
00865         *lpcchSize = dwLength;
00866         SetLastError(ERROR_INSUFFICIENT_BUFFER);
00867         return FALSE;
00868     }
00869 
00870     *lpcchSize = dwLength;
00871     wcscpy(lpProfileDir, szImagePath);
00872 
00873     return TRUE;
00874 }
00875 
00876 
00877 static
00878 BOOL
00879 CheckForLoadedProfile(HANDLE hToken)
00880 {
00881     UNICODE_STRING SidString;
00882     HKEY hKey;
00883 
00884     DPRINT("CheckForLoadedProfile() called\n");
00885 
00886     if (!GetUserSidFromToken(hToken,
00887                              &SidString))
00888     {
00889         DPRINT1("GetUserSidFromToken() failed\n");
00890         return FALSE;
00891     }
00892 
00893     if (RegOpenKeyExW(HKEY_USERS,
00894                       SidString.Buffer,
00895                       0,
00896                       MAXIMUM_ALLOWED,
00897                       &hKey))
00898     {
00899         DPRINT("Profile not loaded\n");
00900         RtlFreeUnicodeString(&SidString);
00901         return FALSE;
00902     }
00903 
00904     RegCloseKey(hKey);
00905 
00906     RtlFreeUnicodeString(&SidString);
00907 
00908     DPRINT("Profile already loaded\n");
00909 
00910     return TRUE;
00911 }
00912 
00913 
00914 BOOL
00915 WINAPI
00916 LoadUserProfileA(HANDLE hToken,
00917                  LPPROFILEINFOA lpProfileInfo)
00918 {
00919     DPRINT ("LoadUserProfileA() not implemented\n");
00920     return FALSE;
00921 }
00922 
00923 
00924 BOOL
00925 WINAPI
00926 LoadUserProfileW(IN HANDLE hToken,
00927                  IN OUT LPPROFILEINFOW lpProfileInfo)
00928 {
00929     WCHAR szUserHivePath[MAX_PATH];
00930     LPWSTR UserName = NULL, Domain = NULL;
00931     DWORD UserNameLength = 0, DomainLength = 0;
00932     PTOKEN_USER UserSid = NULL;
00933     SID_NAME_USE AccountType;
00934     UNICODE_STRING SidString = { 0, 0, NULL };
00935     LONG Error;
00936     BOOL ret = FALSE;
00937     DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
00938 
00939     DPRINT("LoadUserProfileW() called\n");
00940 
00941     /* Check profile info */
00942     if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOW)) ||
00943         (lpProfileInfo->lpUserName == NULL) || (lpProfileInfo->lpUserName[0] == 0))
00944     {
00945         SetLastError(ERROR_INVALID_PARAMETER);
00946         return TRUE;
00947     }
00948 
00949     /* Don't load a profile twice */
00950     if (CheckForLoadedProfile(hToken))
00951     {
00952         DPRINT ("Profile already loaded\n");
00953         lpProfileInfo->hProfile = NULL;
00954         return TRUE;
00955     }
00956 
00957     if (lpProfileInfo->lpProfilePath)
00958     {
00959         wcscpy(szUserHivePath, lpProfileInfo->lpProfilePath);
00960     }
00961     else
00962     {
00963         /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
00964         if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
00965         {
00966             DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
00967             return FALSE;
00968         }
00969     }
00970 
00971     /* Create user hive name */
00972     wcscat(szUserHivePath, L"\\");
00973     wcscat(szUserHivePath, lpProfileInfo->lpUserName);
00974     wcscat(szUserHivePath, L"\\ntuser.dat");
00975     DPRINT("szUserHivePath: %S\n", szUserHivePath);
00976 
00977     /* Create user profile directory if needed */
00978     if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
00979     {
00980         /* Get user sid */
00981         if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) ||
00982             GetLastError() != ERROR_INSUFFICIENT_BUFFER)
00983         {
00984             DPRINT1 ("GetTokenInformation() failed\n");
00985             return FALSE;
00986         }
00987 
00988         UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
00989         if (!UserSid)
00990         {
00991             DPRINT1("HeapAlloc() failed\n");
00992             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00993             goto cleanup;
00994         }
00995 
00996         if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
00997         {
00998             DPRINT1("GetTokenInformation() failed\n");
00999             goto cleanup;
01000         }
01001 
01002         /* Get user name */
01003         do
01004         {
01005             if (UserNameLength > 0)
01006             {
01007                 HeapFree(GetProcessHeap(), 0, UserName);
01008                 UserName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, UserNameLength * sizeof(WCHAR));
01009                 if (!UserName)
01010                 {
01011                     DPRINT1("HeapAlloc() failed\n");
01012                     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01013                     goto cleanup;
01014                 }
01015             }
01016             if (DomainLength > 0)
01017             {
01018                 HeapFree(GetProcessHeap(), 0, Domain);
01019                 Domain = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, DomainLength * sizeof(WCHAR));
01020                 if (!Domain)
01021                 {
01022                     DPRINT1("HeapAlloc() failed\n");
01023                     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01024                     goto cleanup;
01025                 }
01026             }
01027             ret = LookupAccountSidW(NULL,
01028                                     UserSid->User.Sid,
01029                                     UserName,
01030                                     &UserNameLength,
01031                                     Domain,
01032                                     &DomainLength,
01033                                     &AccountType);
01034         } while (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
01035 
01036         if (!ret)
01037         {
01038             DPRINT1("LookupAccountSidW() failed\n");
01039             goto cleanup;
01040         }
01041 
01042         /* Create profile */
01043         /* FIXME: ignore Domain? */
01044         DPRINT("UserName %S, Domain %S\n", UserName, Domain);
01045         ret = CreateUserProfileW(UserSid->User.Sid, UserName);
01046         if (!ret)
01047         {
01048             DPRINT1("CreateUserProfileW() failed\n");
01049             goto cleanup;
01050         }
01051     }
01052 
01053     /* Get user SID string */
01054     ret = GetUserSidFromToken(hToken, &SidString);
01055     if (!ret)
01056     {
01057         DPRINT1("GetUserSidFromToken() failed\n");
01058         goto cleanup;
01059     }
01060     ret = FALSE;
01061 
01062     /* Acquire restore privilege */
01063     if (!AcquireRemoveRestorePrivilege(TRUE))
01064     {
01065         DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
01066         goto cleanup;
01067     }
01068 
01069     /* Load user registry hive */
01070     Error = RegLoadKeyW(HKEY_USERS,
01071                         SidString.Buffer,
01072                         szUserHivePath);
01073     AcquireRemoveRestorePrivilege(FALSE);
01074     if (Error != ERROR_SUCCESS)
01075     {
01076         DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
01077         SetLastError((DWORD)Error);
01078         goto cleanup;
01079     }
01080 
01081     /* Open future HKEY_CURRENT_USER */
01082     Error = RegOpenKeyExW(HKEY_USERS,
01083                           SidString.Buffer,
01084                           0,
01085                           MAXIMUM_ALLOWED,
01086                           (PHKEY)&lpProfileInfo->hProfile);
01087     if (Error != ERROR_SUCCESS)
01088     {
01089         DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
01090         SetLastError((DWORD)Error);
01091         goto cleanup;
01092     }
01093 
01094     ret = TRUE;
01095 
01096 cleanup:
01097     HeapFree(GetProcessHeap(), 0, UserSid);
01098     HeapFree(GetProcessHeap(), 0, UserName);
01099     HeapFree(GetProcessHeap(), 0, Domain);
01100     RtlFreeUnicodeString(&SidString);
01101 
01102     DPRINT("LoadUserProfileW() done\n");
01103     return ret;
01104 }
01105 
01106 
01107 BOOL
01108 WINAPI
01109 UnloadUserProfile(HANDLE hToken,
01110                   HANDLE hProfile)
01111 {
01112     UNICODE_STRING SidString;
01113     LONG Error;
01114 
01115     DPRINT("UnloadUserProfile() called\n");
01116 
01117     if (hProfile == NULL)
01118     {
01119         DPRINT1("Invalide profile handle\n");
01120         SetLastError(ERROR_INVALID_PARAMETER);
01121         return FALSE;
01122     }
01123 
01124     RegCloseKey(hProfile);
01125 
01126     if (!GetUserSidFromToken(hToken,
01127                              &SidString))
01128     {
01129         DPRINT1("GetUserSidFromToken() failed\n");
01130         return FALSE;
01131     }
01132 
01133     DPRINT("SidString: '%wZ'\n", &SidString);
01134 
01135     /* Acquire restore privilege */
01136     if (!AcquireRemoveRestorePrivilege(TRUE))
01137     {
01138         DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
01139         RtlFreeUnicodeString(&SidString);
01140         return FALSE;
01141     }
01142 
01143     /* Unload the hive */
01144     Error = RegUnLoadKeyW(HKEY_USERS,
01145                           SidString.Buffer);
01146 
01147     /* Remove restore privilege */
01148     AcquireRemoveRestorePrivilege(FALSE);
01149 
01150     if (Error != ERROR_SUCCESS)
01151     {
01152         DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error);
01153         RtlFreeUnicodeString(&SidString);
01154         SetLastError((DWORD)Error);
01155         return FALSE;
01156     }
01157 
01158     RtlFreeUnicodeString(&SidString);
01159 
01160     DPRINT("UnloadUserProfile() done\n");
01161 
01162     return TRUE;
01163 }
01164 
01165 BOOL
01166 WINAPI
01167 DeleteProfileW(LPCWSTR lpSidString,
01168                LPCWSTR lpProfilePath,
01169                LPCWSTR lpComputerName)
01170 {
01171    DPRINT1("DeleteProfileW() not implemented!\n");
01172    return FALSE;
01173 }
01174 
01175 BOOL
01176 WINAPI
01177 DeleteProfileA(LPCSTR lpSidString,
01178                LPCSTR lpProfilePath,
01179                LPCSTR lpComputerName)
01180 {
01181    DPRINT1("DeleteProfileA() not implemented!\n");
01182    return FALSE;
01183 }
01184 
01185 /* EOF */

Generated on Sun May 27 2012 04:24:01 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.