Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprofile.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
1.7.6.1
|