//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1997. // // File: util.c // // Contents: // // Classes: // // Functions: // // History: 5-21-97 RichardW Created // //---------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include "moveme.h" #define USER_SHELL_FOLDER TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders") #define PROFILE_LIST_PATH TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList") #define PROFILE_FLAGS TEXT("Flags") #define PROFILE_STATE TEXT("State") #define PROFILE_IMAGE_VALUE_NAME TEXT("ProfileImagePath") #define PROFILE_CENTRAL_PROFILE TEXT("CentralProfile") #define CONFIG_FILE_PATH TEXT("%SystemRoot%\\Profiles\\") #define USER_PREFERENCE TEXT("UserPreference") #define PROFILE_BUILD_NUMBER TEXT("BuildNumber") #define TEMP_PROFILE_NAME_BASE TEXT("TEMP") #define DELETE_ROAMING_CACHE TEXT("DeleteRoamingCache") #define USER_PROFILE_MUTEX TEXT("userenv: User Profile Mutex") LPTSTR SidToString( PSID Sid ) { UNICODE_STRING String ; NTSTATUS Status ; Status = RtlConvertSidToUnicodeString( &String, Sid, TRUE ); if ( NT_SUCCESS( Status ) ) { return String.Buffer ; } return NULL ; } VOID FreeSidString( LPTSTR SidString ) { UNICODE_STRING String ; RtlInitUnicodeString( &String, SidString ); RtlFreeUnicodeString( &String ); } //************************************************************* // // GetUserProfileDirectory() // // Purpose: Returns the root of the user's profile directory. // // Parameters: hToken - User's token // lpProfileDir - Output buffer // lpcchSize - Size of output buffer // // Return: TRUE if successful // FALSE if an error occurs // // Comments: If false is returned, lpcchSize holds the number of // characters needed. // // History: Date Author Comment // 9/18/95 ericflo Created // //************************************************************* BOOL WINAPI GetUserProfileDirectoryFromSid( PSID Sid, LPTSTR lpProfileDir, LPDWORD lpcchSize ) { DWORD dwLength = MAX_PATH * sizeof(TCHAR); DWORD dwType; BOOL bRetVal = FALSE; LPTSTR lpSidString; TCHAR szBuffer[MAX_PATH]; TCHAR szDirectory[MAX_PATH]; HKEY hKey; LONG lResult; // // Retrieve the user's sid string // lpSidString = SidToString( Sid ); if (!lpSidString) { return FALSE; } // // Check the registry // lstrcpy(szBuffer, PROFILE_LIST_PATH); lstrcat(szBuffer, TEXT("\\")); lstrcat(szBuffer, lpSidString); lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey); if (lResult != ERROR_SUCCESS) { FreeSidString(lpSidString); return FALSE; } lResult = RegQueryValueEx(hKey, PROFILE_IMAGE_VALUE_NAME, NULL, &dwType, (LPBYTE) szBuffer, &dwLength); if (lResult != ERROR_SUCCESS) { RegCloseKey (hKey); FreeSidString(lpSidString); return FALSE; } // // Clean up // RegCloseKey(hKey); FreeSidString(lpSidString); // // Expand and get the length of string // ExpandEnvironmentStrings(szBuffer, szDirectory, MAX_PATH); dwLength = lstrlen(szDirectory) + 1; // // Save the string if appropriate // if (lpProfileDir) { if (*lpcchSize >= dwLength) { lstrcpy (lpProfileDir, szDirectory); bRetVal = TRUE; } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } } *lpcchSize = dwLength; return bRetVal; } BOOL SetUserProfileDirectory( PSID Base, PSID Copy ) { LPTSTR lpSidString; TCHAR szBuffer[MAX_PATH]; HKEY hKey; HKEY hNewKey ; LONG lResult; DWORD Disp ; WCHAR CopyBuffer[ MAX_PATH ] ; DWORD CopySize ; DWORD ValueCount ; DWORD ValueNameLen ; DWORD ValueDataLen ; PUCHAR Value ; DWORD Type ; DWORD Index ; DWORD NameSize ; // // Retrieve the user's sid string // lpSidString = SidToString( Base ); if (!lpSidString) { return FALSE; } // // Check the registry // lstrcpy(szBuffer, PROFILE_LIST_PATH); lstrcat(szBuffer, TEXT("\\")); lstrcat(szBuffer, lpSidString); lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey); FreeSidString( lpSidString ); if ( lResult != 0 ) { return FALSE ; } // // Retrieve the user's sid string // lpSidString = SidToString( Copy ); if (!lpSidString) { return FALSE; } // // Check the registry // lstrcpy(szBuffer, PROFILE_LIST_PATH); lstrcat(szBuffer, TEXT("\\")); lstrcat(szBuffer, lpSidString); lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szBuffer, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hNewKey, &Disp ); FreeSidString( lpSidString ); if ( lResult != 0 ) { return FALSE ; } // // Copy Key: // lResult = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &ValueCount, &ValueNameLen, &ValueDataLen, NULL, NULL ); if ( lResult != 0 ) { return FALSE ; } Value = LocalAlloc( LMEM_FIXED, ValueDataLen ); if ( Value ) { Index = 0 ; do { CopySize = ValueDataLen ; NameSize = MAX_PATH ; lResult = RegEnumValue( hKey, Index, CopyBuffer, &NameSize, NULL, &Type, Value, &CopySize ); if ( lResult == 0 ) { lResult = RegSetValueEx( hNewKey, CopyBuffer, 0, Type, Value, CopySize ); } ValueCount-- ; Index ++ ; } while ( ValueCount ); LocalFree( Value ); } lResult = RegSetValueEx( hNewKey, TEXT("Sid"), 0, REG_BINARY, Copy, RtlLengthSid( Copy ) ); if (lResult == 0) { return TRUE; } else { return FALSE; } } LONG MyRegSaveKey( HKEY Key, LPTSTR File, LPSECURITY_ATTRIBUTES lpsa ) { BOOL bResult = TRUE; LONG error; NTSTATUS Status; BOOLEAN WasEnabled; // // Enable the restore privilege // Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &WasEnabled); if (NT_SUCCESS(Status)) { error = RegSaveKey( Key, File, lpsa ); Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, WasEnabled, FALSE, &WasEnabled); } else { error = RtlNtStatusToDosError( Status ); } return error ; } BOOL GetPrimaryDomain( PWSTR Domain ) { NTSTATUS Status, IgnoreStatus; OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE LsaHandle; SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; PPOLICY_PRIMARY_DOMAIN_INFO PrimaryDomainInfo; BOOL PrimaryDomainPresent = FALSE; // // Set up the Security Quality Of Service // SecurityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation; SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SecurityQualityOfService.EffectiveOnly = FALSE; // // Set up the object attributes to open the Lsa policy object // InitializeObjectAttributes(&ObjectAttributes, NULL, 0L, (HANDLE)NULL, NULL); ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService; // // Open the local LSA policy object // Status = LsaOpenPolicy( NULL, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION, &LsaHandle ); if (!NT_SUCCESS(Status)) { DebugLog((DEB_ERROR, "Failed to open local LsaPolicyObject, Status = 0x%lx\n", Status)); return(FALSE); } // // Get the primary domain info // Status = LsaQueryInformationPolicy(LsaHandle, PolicyPrimaryDomainInformation, (PVOID *)&PrimaryDomainInfo); if (!NT_SUCCESS(Status)) { DebugLog((DEB_ERROR, "Failed to query primary domain from Lsa, Status = 0x%lx\n", Status)); IgnoreStatus = LsaClose(LsaHandle); ASSERT(NT_SUCCESS(IgnoreStatus)); return(FALSE); } // // Copy the primary domain name into the return string // if (PrimaryDomainInfo->Sid != NULL) { PrimaryDomainPresent = TRUE; if ( Domain ) { CopyMemory( Domain, PrimaryDomainInfo->Name.Buffer, PrimaryDomainInfo->Name.Length + 2 ); } } // // We're finished with the Lsa // IgnoreStatus = LsaFreeMemory(PrimaryDomainInfo); ASSERT(NT_SUCCESS(IgnoreStatus)); IgnoreStatus = LsaClose(LsaHandle); ASSERT(NT_SUCCESS(IgnoreStatus)); return(PrimaryDomainPresent); }