Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

494 lines
12 KiB

// Copyright (C) 1997 Microsoft Corporation
//
// UserProfilePage class
//
// 9-11-97 sburns
#include "headers.hxx"
#include "UserProfilePage.hpp"
#include "resource.h"
#include "lsm.h"
#include "adsi.hpp"
#include "dlgcomm.hpp"
static const DWORD HELP_MAP[] =
{
IDC_PROFILE, idh_profile_path,
IDC_SCRIPT, idh_profile_logon_script,
IDC_LOCAL, idh_profile_local_path_radio,
IDC_CONNECT, idh_profile_connect_to_radio,
IDC_PATH, idh_profile_local_path_text,
IDC_DRIVE, idh_profile_connect_to_list,
IDC_SHARE, idh_profile_to_text,
0, 0
};
static const wchar_t FIRST_DRIVE_LETTER(L'C');
static const wchar_t LAST_DRIVE_LETTER(L'Z');
UserProfilePage::UserProfilePage(
MMCPropertyPage::NotificationState* state,
const String& userADSIPath)
:
ADSIPage(
IDD_USER_PROFILE,
HELP_MAP,
state,
userADSIPath)
{
LOG_CTOR2(UserProfilePage::ctor, userADSIPath);
}
UserProfilePage::~UserProfilePage()
{
LOG_DTOR2(UserProfilePage, GetADSIPath());
}
static
void
enable(HWND dialog)
{
LOG_FUNCTION(enable);
ASSERT(Win::IsWindow(dialog));
bool enable_path = Win::IsDlgButtonChecked(dialog, IDC_LOCAL);
Win::EnableWindow(Win::GetDlgItem(dialog, IDC_PATH), enable_path);
Win::EnableWindow(Win::GetDlgItem(dialog, IDC_DRIVE), !enable_path);
Win::EnableWindow(Win::GetDlgItem(dialog, IDC_SHARE), !enable_path);
// NTRAID#NTBUG9-425891-2001/06/28-sburns
Win::EnableWindow(Win::GetDlgItem(dialog, IDC_TO_STATIC), !enable_path);
}
void
UserProfilePage::OnInit()
{
LOG_FUNCTION(UserProfilePage::OnInit());
// Setup the controls
Win::Edit_LimitText(Win::GetDlgItem(hwnd, IDC_PROFILE), MAX_PATH);
Win::Edit_LimitText(Win::GetDlgItem(hwnd, IDC_SCRIPT), MAX_PATH);
Win::Edit_LimitText(Win::GetDlgItem(hwnd, IDC_PATH), MAX_PATH);
Win::Edit_LimitText(Win::GetDlgItem(hwnd, IDC_SHARE), MAX_PATH);
// populate the drive list
HWND combo = Win::GetDlgItem(hwnd, IDC_DRIVE);
for (wchar_t d = FIRST_DRIVE_LETTER; d <= LAST_DRIVE_LETTER; d++)
{
Win::ComboBox_AddString(combo, String(1, d) + L":");
}
Win::ComboBox_SetCurSel(combo, LAST_DRIVE_LETTER - FIRST_DRIVE_LETTER);
// load the user properties into the dialog.
HRESULT hr = S_OK;
do
{
SmartInterface<IADsUser> user(0);
hr = ADSI::GetUser(GetADSIPath(), user);
BREAK_ON_FAILED_HRESULT(hr);
BSTR profile;
hr = user->get_Profile(&profile);
BREAK_ON_FAILED_HRESULT(hr);
Win::SetDlgItemText(hwnd, IDC_PROFILE, profile);
::SysFreeString(profile);
BSTR script;
hr = user->get_LoginScript(&script);
BREAK_ON_FAILED_HRESULT(hr);
Win::SetDlgItemText(hwnd, IDC_SCRIPT, script);
::SysFreeString(script);
BSTR home;
hr = user->get_HomeDirectory(&home);
BREAK_ON_FAILED_HRESULT(hr);
_variant_t variant;
hr = user->Get(AutoBstr(ADSI::PROPERTY_LocalDrive), &variant);
BREAK_ON_FAILED_HRESULT(hr);
String local = V_BSTR(&variant);
if (!local.empty())
{
Win::CheckDlgButton(hwnd, IDC_CONNECT, BST_CHECKED);
Win::SetDlgItemText(hwnd, IDC_SHARE, home);
int index = max(0, local[0] - FIRST_DRIVE_LETTER);
Win::ComboBox_SetCurSel(combo, index);
}
else
{
Win::CheckDlgButton(hwnd, IDC_LOCAL, BST_CHECKED);
Win::SetDlgItemText(hwnd, IDC_PATH, home);
}
::SysFreeString(home);
}
while (0);
if (FAILED(hr))
{
popup.Error(
hwnd,
hr,
String::format(
IDS_ERROR_READING_USER,
GetObjectName().c_str()));
Win::PostMessage(Win::GetParent(hwnd), WM_CLOSE, 0, 0);
}
ClearChanges();
enable(hwnd);
}
bool
UserProfilePage::Validate(HWND dialog)
{
LOG_FUNCTION(UserProfilePage::Validate);
ASSERT(Win::IsWindow(dialog));
// profile path is a free-for-all, as it may contain expansion expressions
String script = Win::GetTrimmedDlgItemText(dialog, IDC_SCRIPT);
if (!script.empty())
{
if (FS::GetPathSyntax(script) != FS::SYNTAX_RELATIVE_NO_DRIVE)
{
popup.Gripe(
dialog,
IDC_SCRIPT,
String::format(IDS_BAD_SCRIPT_PATH, script.c_str()) );
return false;
}
}
if (Win::IsDlgButtonChecked(dialog, IDC_LOCAL))
{
// we massage the path one final time here, as the edit box may receive
// kill focus after the page receives kill focus. This happens when
// entering the path then pressing enter.
String dir =
MassagePath(Win::GetTrimmedDlgItemText(dialog, IDC_PATH));
if (!dir.empty())
{
if (FS::GetPathSyntax(dir) != FS::SYNTAX_ABSOLUTE_DRIVE)
{
popup.Gripe(
dialog,
IDC_PATH,
String::format(IDS_BAD_HOME_DIR, dir.c_str()));
return false;
}
if (!FS::PathExists(dir))
{
// attempt to create the path
HRESULT hr = FS::CreateFolder(dir);
if (FAILED(hr))
{
popup.Error(
dialog,
hr,
String::format(IDS_HOME_DIR_CREATE_FAILED, dir.c_str()));
}
}
}
}
else
{
// see massage note above...
String share =
MassagePath(Win::GetTrimmedDlgItemText(dialog, IDC_SHARE));
if (share.empty())
{
popup.Gripe(dialog, IDC_SHARE, IDS_NEED_SHARE_NAME);
return false;
}
else
{
if (FS::GetPathSyntax(share) != FS::SYNTAX_UNC)
{
popup.Gripe(
dialog,
IDC_SHARE,
String::format(IDS_BAD_SHARE_NAME, share.c_str()));
return false;
}
String s = FS::GetRootFolder(share);
// remove the trailing backslash
if (s[s.length() - 1] == L'\\')
{
s.resize(s.length() - 1);
}
Win::WaitCursor waitCur;
DWORD attrs = 0;
HRESULT hr = Win::GetFileAttributes(s, attrs);
if (FAILED(hr))
{
popup.Gripe(
dialog,
IDC_SHARE,
hr,
String::format(IDS_CANT_ACCESS_SHARE, s.c_str()));
return false;
}
}
}
return true;
}
bool
UserProfilePage::OnKillActive()
{
LOG_FUNCTION(UserProfilePage::OnKillActive);
if (!Validate(hwnd))
{
// refuse to relinquish focus
Win::SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
}
return true;
}
// if %username% is at the end of the string, replace it with the current
// username.
String
UserProfilePage::MassagePath(const String& path)
{
LOG_FUNCTION2(UserProfilePage::MassagePath, path);
static const String USERNAME = String::load(IDS_USERNAME).to_upper();
if (path.length() >= USERNAME.length())
{
String path_copy = path;
path_copy.to_upper();
size_t pos = path_copy.rfind(USERNAME);
if (pos == path.length() - USERNAME.length())
{
return path.substr(0, pos) + GetObjectName();
}
}
return path;
}
bool
UserProfilePage::OnApply(bool /* isClosing */)
{
LOG_FUNCTION(UserProfilePage::OnApply);
if (!WasChanged())
{
return true;
}
// don't need to call validate; kill active is sent before apply
HRESULT hr = S_OK;
do
{
SmartInterface<IADsUser> user(0);
hr = ADSI::GetUser(GetADSIPath(), user);
BREAK_ON_FAILED_HRESULT(hr);
if (WasChanged(IDC_PROFILE))
{
String profile =
MassagePath(Win::GetTrimmedDlgItemText(hwnd, IDC_PROFILE));
hr = user->put_Profile(AutoBstr(profile));
BREAK_ON_FAILED_HRESULT(hr);
}
if (WasChanged(IDC_SCRIPT))
{
String script = Win::GetTrimmedDlgItemText(hwnd, IDC_SCRIPT);
hr = user->put_LoginScript(AutoBstr(script));
BREAK_ON_FAILED_HRESULT(hr);
}
if (Win::IsDlgButtonChecked(hwnd, IDC_LOCAL))
{
if (WasChanged(IDC_LOCAL) || WasChanged(IDC_PATH))
{
// The local path button was checked, and the user clicked it.
String dir =
MassagePath(Win::GetTrimmedDlgItemText(hwnd, IDC_PATH));
hr = user->put_HomeDirectory(AutoBstr(dir));;
BREAK_ON_FAILED_HRESULT(hr);
// write an empty string to the home drive
String blank;
_variant_t variant;
variant = blank.c_str();
hr = user->Put(AutoBstr(ADSI::PROPERTY_LocalDrive), variant);
BREAK_ON_FAILED_HRESULT(hr);
}
}
else
{
if (
WasChanged(IDC_CONNECT)
|| WasChanged(IDC_SHARE)
|| WasChanged(IDC_DRIVE))
{
// The connect to: button was checked, and the user clicked it.
String share =
MassagePath(Win::GetTrimmedDlgItemText(hwnd, IDC_SHARE));
hr = user->put_HomeDirectory(AutoBstr(share));
BREAK_ON_FAILED_HRESULT(hr);
// Attempt to create the folder
hr = FS::CreateFolder(share);
if (FAILED(hr))
{
popup.Error(
hwnd,
hr,
String::format(IDS_CANT_CREATE_FOLDER, share.c_str()));
}
int index =
Win::ComboBox_GetCurSel(Win::GetDlgItem(hwnd, IDC_DRIVE));
String drive =
String(1, (wchar_t)min(FIRST_DRIVE_LETTER + index, LAST_DRIVE_LETTER))
+ L":";
_variant_t variant;
variant = drive.c_str();
hr = user->Put(AutoBstr(ADSI::PROPERTY_LocalDrive), variant);
BREAK_ON_FAILED_HRESULT(hr);
}
}
// commit the property changes
hr = user->SetInfo();
BREAK_ON_FAILED_HRESULT(hr);
SetChangesApplied();
ClearChanges();
}
while (0);
if (FAILED(hr))
{
popup.Error(
hwnd,
hr,
String::format(
IDS_ERROR_SETTING_USER_PROPERTIES,
GetObjectName().c_str()));
}
return true;
}
bool
UserProfilePage::OnCommand(
HWND /* windowFrom */ ,
unsigned controlIDFrom,
unsigned code)
{
// LOG_FUNCTION(UserProfilePage::OnCommand);
switch (controlIDFrom)
{
case IDC_LOCAL:
case IDC_CONNECT:
{
if (code == BN_CLICKED)
{
SetChanged(controlIDFrom);
enable(hwnd);
Win::PropSheet_Changed(Win::GetParent(hwnd), hwnd);
}
break;
}
case IDC_PROFILE:
case IDC_SCRIPT:
case IDC_PATH:
case IDC_SHARE:
{
switch (code)
{
case EN_CHANGE:
{
SetChanged(controlIDFrom);
enable(hwnd);
Win::PropSheet_Changed(Win::GetParent(hwnd), hwnd);
break;
}
case EN_KILLFOCUS:
{
Win::SetDlgItemText(
hwnd,
controlIDFrom,
MassagePath(
Win::GetTrimmedDlgItemText(hwnd, controlIDFrom)));
break;
}
default:
{
// do nothing
break;
}
}
break;
}
case IDC_DRIVE:
{
if (code == CBN_SELCHANGE)
{
SetChanged(controlIDFrom);
enable(hwnd);
Win::PropSheet_Changed(Win::GetParent(hwnd), hwnd);
}
}
default:
{
break;
}
}
return true;
}