windows-nt/Source/XPSP1/NT/ds/security/tools/moveme/moveme.c
2020-09-26 16:20:57 +08:00

1157 lines
30 KiB
C

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1997.
//
// File: moveme.c
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 5-21-97 RichardW Created
//
//----------------------------------------------------------------------------
#include "moveme.h"
#include "dialogs.h"
#include <stdlib.h>
#define APPNAME TEXT("fail")
#define FILENAME TEXT("moveme.ini")
ULONG MoveOptions = MOVE_UPDATE_SECURITY | MOVE_DO_PROFILE ;
WCHAR MachDomain[ DNLEN * 2 ];
WCHAR SourceDomain[ DNLEN * 2 ];
WCHAR DestDomain[ DNLEN * 2 ];
WCHAR UserName[ UNLEN * 2 ];
PSID OldSid ;
PSID NewSid ;
HICON MyIcon ;
PDOMAIN_CONTROLLER_INFO DcInfo ;
PDOMAIN_CONTROLLER_INFO DestDcInfo ;
OSVERSIONINFOEX VersionInfo ;
DWORD ProfileSection[] = { IDD_RADIO_MAKECOPY, IDD_RADIO_REFER_TO_SAME, IDD_RADIO_MAKE_ROAM };
VOID
EnableSection(
HWND hDlg,
BOOL Enable,
PDWORD IdList,
DWORD Count
)
{
DWORD i ;
for ( i = 0 ; i < Count ; i++ )
{
EnableWindow( GetDlgItem( hDlg, IdList[ i ]), Enable );
}
}
VOID
DumpState(
VOID
)
{
UNICODE_STRING Sid ;
WCHAR PrivateInt[ 16 ];
swprintf( PrivateInt, L"%d", VersionInfo.dwBuildNumber );
WritePrivateProfileString( APPNAME, TEXT("Build"), PrivateInt, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("MachDomain"), MachDomain, FILENAME);
WritePrivateProfileString( APPNAME, TEXT("SourceDomain"), SourceDomain, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DestDomain"), DestDomain, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("UserName"), UserName, FILENAME );
if ( DcInfo )
{
WritePrivateProfileString( APPNAME, TEXT("DcInfo.name"), DcInfo->DomainControllerName, FILENAME);
WritePrivateProfileString( APPNAME, TEXT("DcInfo.address"), DcInfo->DomainControllerAddress, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DcInfo.domainname"), DcInfo->DomainName, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DcInfo.treename"), DcInfo->DnsForestName, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DcInfo.dcsite"), DcInfo->DcSiteName, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DcInfo.clientsite"), DcInfo->ClientSiteName, FILENAME );
//WritePrivateProfileInt( APPNAME, TEXT("DcInfo.Flags"), DcInfo->Flags, FILENAME );
}
if ( DestDcInfo )
{
WritePrivateProfileString( APPNAME, TEXT("DestDcInfo.name"), DestDcInfo->DomainControllerName, FILENAME);
WritePrivateProfileString( APPNAME, TEXT("DestDcInfo.address"), DestDcInfo->DomainControllerAddress, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DestDcInfo.domainname"), DestDcInfo->DomainName, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DestDcInfo.treename"), DestDcInfo->DnsForestName, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DestDcInfo.dcsite"), DestDcInfo->DcSiteName, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("DestDcInfo.clientsite"), DestDcInfo->ClientSiteName, FILENAME );
}
if ( OldSid )
{
RtlConvertSidToUnicodeString( &Sid, OldSid, TRUE );
WritePrivateProfileString( APPNAME, TEXT("OldSid"), Sid.Buffer, FILENAME );
RtlFreeUnicodeString( &Sid );
}
else
{
WritePrivateProfileString( APPNAME, TEXT("OldSid"), TEXT("<none>"), FILENAME );
}
if ( NewSid )
{
RtlConvertSidToUnicodeString( &Sid, NewSid, TRUE );
WritePrivateProfileString( APPNAME, TEXT("NewSid"), Sid.Buffer, FILENAME );
RtlFreeUnicodeString( &Sid );
}
else
{
WritePrivateProfileString( APPNAME, TEXT("NewSid"), TEXT("<none>"), FILENAME );
}
}
VOID
Fail(
HWND hWnd,
PWSTR Failure,
PWSTR Description,
DWORD Code,
PWSTR Message
)
{
UNICODE_STRING Sid ;
WCHAR Msg[MAX_PATH];
WCHAR foo[MAX_PATH];
UpdateUi(0,100);
StopUiThread();
DumpState();
WritePrivateProfileString( APPNAME, TEXT("Failure"), Failure, FILENAME );
WritePrivateProfileString( APPNAME, TEXT("Desc"), Description, FILENAME );
wsprintf( Msg, L"%d (%#x)", Code, Code );
WritePrivateProfileString( APPNAME, TEXT("Code"), Msg, FILENAME );
ExpandEnvironmentStrings( TEXT("%windir%"), foo, MAX_PATH );
_snwprintf( Msg, MAX_PATH, TEXT("%ws Please mail the file %ws in %ws to 'ntdsbug'"),
Message ? Message : TEXT("An unrecoverable error occurred, and has prevented you from joining the NTDEV rollout."),
FILENAME, foo );
MessageBox( hWnd, Msg, TEXT("Error"), MB_ICONSTOP | MB_OK );
ExitProcess( GetLastError() );
}
PSECURITY_DESCRIPTOR
MakeUserSD(
PSID UserSid,
ACCESS_MASK Mask
)
{
PSECURITY_DESCRIPTOR psd ;
PACL Dacl ;
DWORD DaclLen ;
PACCESS_ALLOWED_ACE Ace ;
PSID LocalSystem ;
SID_IDENTIFIER_AUTHORITY NtAuth = SECURITY_NT_AUTHORITY ;
AllocateAndInitializeSid( &NtAuth, 1,
SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0,
&LocalSystem );
psd = LocalAlloc( LMEM_FIXED, sizeof( SECURITY_DESCRIPTOR ) );
DaclLen = (sizeof( ACCESS_ALLOWED_ACE ) + RtlLengthSid( UserSid )) * 2 ;
Dacl = LocalAlloc( LMEM_FIXED, DaclLen );
if ( !psd || !Dacl)
{
return NULL ;
}
InitializeSecurityDescriptor( psd, SECURITY_DESCRIPTOR_REVISION );
InitializeAcl( Dacl, DaclLen, ACL_REVISION );
SetSecurityDescriptorDacl( psd, TRUE, Dacl, FALSE );
AddAccessAllowedAce( Dacl, ACL_REVISION, Mask, UserSid );
GetAce( Dacl, 0, &Ace );
Ace->Header.AceFlags |= CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE ;
AddAccessAllowedAce( Dacl, ACL_REVISION, Mask, LocalSystem );
GetAce( Dacl, 1, &Ace );
Ace->Header.AceFlags |= CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE ;
return psd ;
}
RecurseWhackKey(
HKEY ParentKey,
PWSTR SubKey,
PSECURITY_DESCRIPTOR psd
)
{
HKEY Key ;
int err ;
NTSTATUS Status ;
WCHAR SubKeys[ 128 ];
DWORD dwSize ;
DWORD dwIndex ;
FILETIME ftTime ;
err = RegOpenKeyEx(
ParentKey,
SubKey,
0,
WRITE_DAC | WRITE_OWNER,
&Key );
if ( err == 0 )
{
Status = NtSetSecurityObject( Key,
OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
psd );
if ( NT_SUCCESS( Status ) )
{
RegCloseKey( Key );
err = RegOpenKeyEx(
ParentKey,
SubKey,
0,
KEY_READ | KEY_WRITE,
&Key );
if ( err )
{
return err;
}
dwIndex = 0 ;
dwSize = sizeof( SubKeys ) / sizeof( WCHAR );
while ( RegEnumKeyEx( Key,
dwIndex,
SubKeys,
&dwSize,
NULL,
NULL,
NULL,
&ftTime ) == ERROR_SUCCESS )
{
RecurseWhackKey( Key, SubKeys, psd );
dwIndex++ ;
dwSize = sizeof( SubKeys ) / sizeof( WCHAR );
}
}
RegCloseKey( Key );
}
return err ;
}
VOID
DealWithPstore(
PSID UserSid
)
{
HKEY hKey = NULL;
int err ;
BOOLEAN WasEnabled ;
NTSTATUS Status ;
PSECURITY_DESCRIPTOR psd ;
Status = RtlAdjustPrivilege( SE_TAKE_OWNERSHIP_PRIVILEGE, TRUE, FALSE, &WasEnabled );
if ( !NT_SUCCESS( Status ))
{
return ;
}
err = RegOpenKeyEx(
HKEY_CURRENT_USER,
TEXT("Software\\Microsoft"),
0,
KEY_READ | KEY_WRITE,
&hKey );
if( err != 0 )
{
return ;
}
psd = MakeUserSD( UserSid, KEY_ALL_ACCESS );
SetSecurityDescriptorOwner( psd, UserSid, FALSE );
RecurseWhackKey( hKey, TEXT("Protected Storage System Provider"), psd );
}
BOOL
MoveMe(
HWND hWnd,
LPWSTR OldProfile,
LPWSTR NewProfile
)
{
HKEY hKeyCU ;
int err ;
WCHAR TempPath[ MAX_PATH ];
WCHAR TempFile[ MAX_PATH ];
WCHAR TempPath2[ MAX_PATH ];
HANDLE Token ;
DWORD PathLength ;
BOOL Ret ;
WCHAR UserNameEx[ 64 ];
DWORD Index = 0 ;
SECURITY_ATTRIBUTES sa ;
if ( MoveOptions & MOVE_MAKE_ROAM )
{
GetTempPath( MAX_PATH, TempPath );
GetTempFileName( TempPath, TEXT("prf"), GetTickCount() & 0xFFFF, TempFile );
UpdateUi( IDS_COPYING_USER_HIVE, 30 );
err = MyRegSaveKey( HKEY_CURRENT_USER,
TempFile,
NULL );
if ( err )
{
Fail( hWnd, TEXT("Save HKCU failed"), TEXT(""), err, NULL);
return err ;
}
if (OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token ))
{
PathLength = MAX_PATH ;
if (!GetUserProfileDirectory( Token, TempPath, &PathLength ))
{
Fail( hWnd, TEXT("Can't get current profile dir"), TEXT(""),
GetLastError(), NULL );
}
}
else
{
Fail( hWnd, TEXT("Can't open process token?"), TEXT(""), GetLastError(), NULL );
}
UpdateUi( IDS_CREATING_NEW_PROFILE, 60 );
Index = 64 ;
GetUserName( UserNameEx, &Index );
swprintf( TempPath2, TEXT("\\\\scratch\\scratch\\%ws\\Profile"), UserNameEx );
sa.nLength = sizeof( sa );
sa.bInheritHandle = FALSE ;
sa.lpSecurityDescriptor = MakeUserSD( NewSid, FILE_ALL_ACCESS );
if ( CreateDirectory( TempPath2, NULL ) )
{
UpdateUi( IDS_CREATING_NEW_PROFILE, 70 );
if ( ! CopyProfileDirectory( TempPath,
TempPath2,
CPD_FORCECOPY |
CPD_IGNORECOPYERRORS |
CPD_IGNOREHIVE |
CPD_SHOWSTATUS ) )
{
if ( GetLastError() == 997 )
{
//
// Looks like the dreaded pstore key problem. Sigh.
//
DealWithPstore( NewSid );
if ( ! CopyProfileDirectory( TempPath,
TempPath2,
CPD_FORCECOPY |
CPD_IGNORECOPYERRORS |
CPD_IGNOREHIVE |
CPD_SHOWSTATUS ) )
{
//
// Terminal, now bail:
//
Fail( hWnd, TEXT("Can't copy profile dir, even after whacking pstore key"), TempPath2, GetLastError(), NULL );
return GetLastError() ;
}
}
else
{
Fail( hWnd, TEXT("Can't copy profile directory"), TempPath2, GetLastError(), NULL );
return GetLastError() ;
}
}
}
else
{
Fail( hWnd, TEXT("Can't create new directory"), TempPath2, GetLastError(), NULL );
return GetLastError() ;
}
wcscat( TempPath2, TEXT("\\ntuser.dat") );
if ( ! CopyFile( TempFile, TempPath2, FALSE ) )
{
Fail( hWnd, TEXT("Can't copy hive"), TempPath2, GetLastError(), NULL );
}
DeleteFile( TempFile );
return GetLastError() ;
}
if ( MoveOptions & MOVE_COPY_PROFILE )
{
GetTempPath( MAX_PATH, TempPath );
GetTempFileName( TempPath, TEXT("prf"), GetTickCount() & 0xFFFF, TempFile );
UpdateUi( IDS_COPYING_USER_HIVE, 30 );
err = MyRegSaveKey( HKEY_CURRENT_USER,
TempFile,
NULL );
if ( err )
{
Fail( hWnd, TEXT("Save HKCU failed"), TEXT(""), err, NULL);
return err ;
}
if (OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token ))
{
PathLength = MAX_PATH ;
if (!GetUserProfileDirectory( Token, TempPath, &PathLength ))
{
Fail( hWnd, TEXT("Can't get current profile dir"), TEXT(""),
GetLastError(), NULL );
}
}
else
{
Fail( hWnd, TEXT("Can't open process token?"), TEXT(""), GetLastError(), NULL );
}
UpdateUi( IDS_CREATING_NEW_PROFILE, 60 );
Ret = CreateUserProfile( NewSid, UserName, TempFile, NULL, 0 );
if ( !Ret )
{
if ( GetLastError() == 997 )
{
//
// Looks like the dreaded pstore key problem. Sigh.
//
DeleteFile( TempFile );
DealWithPstore( OldSid );
err = MyRegSaveKey( HKEY_CURRENT_USER,
TempFile,
NULL );
if ( ! CreateUserProfile( NewSid, UserName, TempFile, NULL, 0 ) )
{
//
// Terminal, now bail:
//
DeleteFile( TempFile );
Fail( hWnd, TEXT("Can't copy profile dir, even after whacking pstore key"), TEXT(""), GetLastError(), NULL );
return GetLastError() ;
}
Ret = TRUE ;
}
else
{
DeleteFile( TempFile );
Fail( hWnd, TEXT( "CreateUserProfile failed"), TEXT(""), GetLastError(), NULL );
}
}
DeleteFile( TempFile );
UpdateUi( IDS_CREATING_NEW_PROFILE, 65 );
if ( Ret )
{
//
// Okay, we have created a shell profile based on the current
// profile. Now, copy the rest of the gunk over it:
//
PathLength = MAX_PATH ;
GetUserProfileDirectoryFromSid( NewSid, TempPath2, &PathLength );
UpdateUi( IDS_COPYING_OLD_PROFILE, 90 );
if ( !CopyProfileDirectory( TempPath,
TempPath2,
CPD_FORCECOPY |
CPD_IGNORECOPYERRORS |
CPD_IGNOREHIVE ) )
{
Fail( hWnd, TEXT("CopyProfileDirectory failed"), TEXT(""), GetLastError(), NULL );
}
}
else
{
//
// Failed to create the shell profile. Why?
//
Fail( hWnd, TEXT("Failed to create profile"), TEXT(""), GetLastError(), NULL );
}
}
else
{
SetUserProfileDirectory( OldSid, NewSid );
}
if ( MoveOptions & MOVE_CHANGE_DOMAIN )
{
NET_API_STATUS NetStatus ;
UpdateUi( IDS_MOVE_DOMAIN, 50 );
NetStatus = NetJoinDomain( NULL, DestDomain,NULL,
TEXT("ntdev"), TEXT("ntdev"),
NETSETUP_JOIN_DOMAIN |
NETSETUP_ACCT_CREATE );
UpdateUi( IDS_MOVE_DOMAIN, 95 );
}
return TRUE ;
}
VOID
DoSecurity(
HWND hDlg
)
{
int err ;
HKEY hKey ;
DWORD Disp ;
NET_API_STATUS NetStatus ;
LOCALGROUP_MEMBERS_INFO_0 LocalGroupInfo0 ;
UpdateUi( IDS_SEC_LOCAL_SETTINGS, 50 );
err = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
TEXT("System\\CurrentControlSet\\Control\\Lsa\\MSV1_0"),
0,
TEXT(""),
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hKey,
&Disp );
if ( err == 0 )
{
err = RegSetValueEx( hKey,
TEXT("PreferredDomain"),
0,
REG_SZ,
(PUCHAR) SourceDomain,
(wcslen( SourceDomain ) + 1) * 2 );
if ( err == 0 )
{
err = RegSetValueEx( hKey,
TEXT("MappedDomain"),
0,
REG_SZ,
(PUCHAR) DestDomain,
(wcslen( DestDomain ) + 1 ) * 2 );
}
RegCloseKey( hKey );
}
else
{
Fail( hDlg, TEXT("Unable to open LSA key"), TEXT(""), err, TEXT("Unable to update rollout keys, you may not have permission.") );
}
UpdateUi( IDS_SEC_LOCAL_ADMIN, 90 );
LocalGroupInfo0.lgrmi0_sid = NewSid ;
NetStatus = NetLocalGroupAddMembers(
NULL,
L"Administrators",
0,
(LPBYTE) &LocalGroupInfo0,
1 );
}
BOOL
Initialize(
VOID
)
{
ULONG Length ;
HANDLE hToken ;
PUNICODE_STRING User ;
PUNICODE_STRING Domain ;
UNICODE_STRING TargetDomainStr ;
NTSTATUS Status ;
PSID Sid ;
PSID AdminSid ;
PTOKEN_USER UserSid ;
DWORD SidLength ;
PBYTE DCName ;
NET_API_STATUS NetStatus ;
WCHAR RefDomain[ DNLEN + 2 ];
ULONG RefDomainLength ;
SID_NAME_USE NameUse ;
BOOL IsMember ;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY ;
RaiseUi( NULL, L"Initializing..." );
UpdateUi( IDS_INIT_READ_NAMES, 5 );
Status = NtOpenProcessToken( NtCurrentProcess(),
TOKEN_QUERY,
&hToken );
if ( NT_SUCCESS( Status ) )
{
UserSid = LocalAlloc( LMEM_FIXED, 64 );
if ( UserSid )
{
Status = NtQueryInformationToken( hToken,
TokenUser,
UserSid,
64,
&SidLength );
if ( NT_SUCCESS( Status ) )
{
OldSid = UserSid->User.Sid ;
}
}
AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0 ,0, 0,
&AdminSid );
if ( CheckTokenMembership( hToken, AdminSid, &IsMember ) )
{
if ( !IsMember )
{
Fail( NULL, TEXT("Not an administrator"), TEXT(""), GetLastError(),
TEXT( "You must be an administrator on this machine to run this utility." ) );
}
}
NtClose( hToken );
}
if ( !NT_SUCCESS( Status ) )
{
Fail( NULL, TEXT("Reading SID"), TEXT(""), Status, NULL );
}
UpdateUi( IDS_INIT_READ_NAMES, 25 );
Status = LsaGetUserName( &User, &Domain );
if ( !NT_SUCCESS( Status ) )
{
Fail( NULL, TEXT("Getting user name"), TEXT(""), Status, NULL );
return FALSE ;
}
RtlInitUnicodeString( &TargetDomainStr, DestDomain );
if ( RtlEqualUnicodeString( &TargetDomainStr, Domain, TRUE ) )
{
MoveOptions &= ~MOVE_DO_PROFILE ;
MoveOptions |= MOVE_NO_PROFILE ;
}
UpdateUi( IDS_INIT_READ_NAMES, 35 );
GetPrimaryDomain( MachDomain );
UpdateUi( IDS_INIT_READ_NAMES, 45 );
NetStatus = DsGetDcName( NULL, MachDomain, NULL, NULL,
DS_FORCE_REDISCOVERY |
DS_DIRECTORY_SERVICE_REQUIRED |
DS_KDC_REQUIRED,
&DcInfo );
UpdateUi( IDS_INIT_READ_NAMES, 55 );
if ( (MoveOptions & MOVE_SOURCE_SUPPLIED) == 0)
{
CopyMemory( SourceDomain, Domain->Buffer, Domain->Length );
SourceDomain[ Domain->Length / sizeof(WCHAR) ] = L'\0';
}
CopyMemory( UserName, User->Buffer, User->Length );
UserName[ User->Length / sizeof(WCHAR) ] = L'\0';
LsaFreeMemory( User );
LsaFreeMemory( Domain );
//
// Dest Domain must be filled in by caller. So, try to look up
// the new SID:
//
SidLength = RtlLengthRequiredSid( 6 );
Sid = LocalAlloc( LMEM_FIXED, SidLength );
if ( !Sid )
{
return FALSE ;
}
UpdateUi( IDS_INIT_DISCOVER_DCS, 75 );
RefDomainLength = DNLEN + 2 ;
NetStatus = DsGetDcName( NULL, DestDomain, NULL, NULL,
DS_FORCE_REDISCOVERY |
DS_DIRECTORY_SERVICE_REQUIRED |
DS_KDC_REQUIRED,
&DestDcInfo );
if ( NetStatus == 0 )
{
UpdateUi( IDS_INIT_LOOKUP_ACCOUNTS, 95 );
if ( LookupAccountName( (PWSTR) DestDcInfo->DomainControllerAddress,
UserName,
Sid,
&SidLength,
RefDomain,
&RefDomainLength,
&NameUse )
)
{
if (_wcsicmp( RefDomain, DestDomain ) == 0 )
{
NewSid = Sid ;
}
else
{
Fail( NULL, TEXT("No account for user"), UserName, GetLastError(),
TEXT( "There is no account for you on the destination domain. Please contact NUTS for an account." ) );
}
}
else
{
Fail( NULL, TEXT("Can't look up account name"), TEXT(""), GetLastError(), NULL );
}
}
else
{
Fail( NULL, TEXT("No DC available"), DestDomain, NetStatus,
TEXT("No Domain Controllers were available for the destination domain. Please try again later."));
}
UpdateUi( IDS_INIT_LOOKUP_ACCOUNTS, 100 );
return TRUE ;
}
VOID
Usage(
VOID
)
{
wprintf( TEXT("Usage:\n"));
wprintf( TEXT("\tmoveme DOMAINNAME\n"));
exit( 0 );
}
VOID
DoArgs(
int argc,
WCHAR * argv[]
)
{
int i;
PWSTR Scan;
wcscpy( DestDomain, L"NTDEV");
i = 1 ;
while ( i < argc )
{
if ( (*argv[i] != L'-') &&
(*argv[i] != L'/') )
{
wcscpy( DestDomain, argv[i] );
}
else
{
switch ( *(argv[i]+1) )
{
case L'F':
case L'f':
MoveOptions |= MOVE_NO_UI ;
break;
case L'D':
case L'd':
MoveOptions |= MOVE_SOURCE_SUPPLIED ;
Scan = argv[i];
while ( *Scan && (*Scan != ':'))
{
Scan++;
}
if ( *Scan )
{
Scan++;
wcscpy( SourceDomain, Scan );
}
break;
case L'P':
case L'p':
if ( *(argv[i]+2) == L'-' )
{
MoveOptions &= ~MOVE_DO_PROFILE ;
}
else
{
MoveOptions |= MOVE_DO_PROFILE ;
}
break;
case L'W':
case L'w':
MoveOptions = MOVE_WHACK_PSTORE ;
break;
default:
Usage();
}
}
i++ ;
}
}
BOOL
DoIt(
HWND hDlg
)
{
RaiseUi( hDlg, L"Migrating User Information...");
if ( MoveOptions & MOVE_DO_PROFILE )
{
MoveMe( hDlg, NULL, NULL );
}
if ( MoveOptions & MOVE_UPDATE_SECURITY )
{
DoSecurity( hDlg );
}
UpdateUi( 0, 100 );
return TRUE ;
}
INT_PTR
WINAPI
PromptDlg(
HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam)
{
WCHAR Buffer[ MAX_PATH ];
switch ( Message )
{
case WM_INITDIALOG:
MyIcon = LoadImage( GetModuleHandle(NULL),
MAKEINTRESOURCE( 1 ),
IMAGE_ICON,
64, 72,
LR_DEFAULTCOLOR );
if ( MyIcon )
{
SendMessage( GetDlgItem( hDlg, IDD_MAIN_ICON ),
STM_SETICON,
(WPARAM) MyIcon, 0 );
}
swprintf( Buffer, TEXT("Account Domain: %ws"), SourceDomain );
SetDlgItemText( hDlg, IDD_DOMAIN_LINE, Buffer );
swprintf( Buffer, TEXT("Machine Domain: %ws"), MachDomain );
SetDlgItemText( hDlg, IDD_WKSTA_DOMAIN, Buffer );
swprintf( Buffer, TEXT("This tool will adjust a number of settings on your machine to move to the %ws domain."),
DestDomain );
SetDlgItemText( hDlg, IDD_ABOUT, Buffer );
CheckDlgButton( hDlg, IDD_RADIO_MAKECOPY, BST_CHECKED );
if ( MoveOptions & MOVE_NO_PROFILE )
{
CheckDlgButton( hDlg, IDD_PROFILE_CHECK, BST_UNCHECKED );
EnableSection( hDlg, FALSE, ProfileSection,
sizeof( ProfileSection ) /sizeof(DWORD) );
}
else
{
CheckDlgButton( hDlg, IDD_PROFILE_CHECK, BST_CHECKED );
}
CheckDlgButton( hDlg, IDD_UPDATE_SEC, BST_CHECKED );
EnableWindow( GetDlgItem( hDlg, IDD_UPDATE_SEC ), FALSE );
//
// If we're already there, forget it.
//
if ( _wcsicmp( MachDomain, DestDomain ) == 0 )
{
EnableWindow( GetDlgItem( hDlg, IDD_MOVE_MACHINE), FALSE );
}
//
// If the domain already has a DS DC, forget it.
//
if ( DcInfo && DcInfo->Flags & DS_DS_FLAG )
{
EnableWindow( GetDlgItem( hDlg, IDD_MOVE_MACHINE), FALSE );
}
return FALSE ;
case WM_COMMAND:
switch (LOWORD( wParam ) )
{
case IDCANCEL:
EndDialog( hDlg, IDCANCEL );
break;
case IDOK:
//
// Gather settings
//
if ( IsDlgButtonChecked( hDlg, IDD_PROFILE_CHECK ) == BST_CHECKED )
{
MoveOptions |= MOVE_DO_PROFILE ;
if ( IsDlgButtonChecked( hDlg, IDD_RADIO_MAKECOPY ) == BST_CHECKED )
{
MoveOptions |= MOVE_COPY_PROFILE ;
}
if ( IsDlgButtonChecked( hDlg, IDD_RADIO_MAKE_ROAM ) == BST_CHECKED )
{
MoveOptions |= MOVE_MAKE_ROAM ;
}
}
if ( IsDlgButtonChecked( hDlg, IDD_MOVE_MACHINE ) == BST_CHECKED )
{
MoveOptions |= MOVE_CHANGE_DOMAIN ;
}
if ( IsDlgButtonChecked( hDlg, IDD_UPDATE_SEC ) == BST_CHECKED )
{
MoveOptions |= MOVE_UPDATE_SECURITY ;
}
DumpState();
DoIt( hDlg );
EndDialog( hDlg, IDOK );
break;
case IDD_PROFILE_CHECK:
if ( HIWORD( wParam ) == BN_CLICKED )
{
if ( IsDlgButtonChecked( hDlg, IDD_PROFILE_CHECK )
== BST_CHECKED )
{
EnableSection( hDlg,
TRUE,
ProfileSection,
sizeof( ProfileSection ) / sizeof(DWORD) );
}
else
{
EnableSection( hDlg, FALSE, ProfileSection,
sizeof( ProfileSection ) /sizeof(DWORD) );
}
return TRUE ;
}
break;
}
return TRUE ;
default:
return FALSE ;
}
}
void
__cdecl
wmain (int argc, WCHAR *argv[])
{
int Result ;
NTSTATUS Status ;
BOOLEAN WasEnabled ;
VersionInfo.dwOSVersionInfoSize = sizeof( VersionInfo );
GetVersionEx( (LPOSVERSIONINFOW) &VersionInfo );
#if DBG
InitDebugSupport();
#endif
InitCommonControls();
DoArgs( argc, argv );
CreateUiThread();
if (!Initialize())
{
StopUiThread();
ExitProcess( GetLastError() );
}
if ( MoveOptions & MOVE_WHACK_PSTORE )
{
DealWithPstore( NewSid );
}
if ( MoveOptions & MOVE_NO_UI )
{
MoveOptions |= MOVE_COPY_PROFILE | MOVE_UPDATE_SECURITY ;
DoIt( NULL );
}
Result = (int)DialogBox( GetModuleHandle( NULL ),
MAKEINTRESOURCE( IDD_MAIN_DLG ),
NULL,
PromptDlg );
if ( Result == IDOK )
{
Result = MessageBox( NULL, L"The changes require a reboot. Reboot now?",
L"Move Tool",
MB_ICONINFORMATION | MB_YESNO );
if ( Result == IDYES )
{
Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
TRUE, FALSE,
&WasEnabled );
if ( NT_SUCCESS( Status ) )
{
ExitWindowsEx( EWX_FORCE | EWX_REBOOT, 0 );
}
}
}
}