/* -*- Mode: C; tab-width: 4 -*- * * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <Secret.h> #include "RegistrationPage.h" #include "resource.h" #include "ConfigPropertySheet.h" extern "C" { #include <ClientCommon.h> } #include <WinServices.h> #define MAX_KEY_LENGTH 255 IMPLEMENT_DYNCREATE(CRegistrationPage, CPropertyPage) //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::CRegistrationPage //--------------------------------------------------------------------------------------------------------------------------- CRegistrationPage::CRegistrationPage() : CPropertyPage(CRegistrationPage::IDD), m_ignoreChanges( false ), m_hostnameSetupKey( NULL ), m_registrationSetupKey( NULL ), m_statusKey( NULL ) { //{{AFX_DATA_INIT(CRegistrationPage) //}}AFX_DATA_INIT OSStatus err; err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\Hostnames", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_hostnameSetupKey, NULL ); check_noerr( err ); err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_registrationSetupKey, NULL ); check_noerr( err ); err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\State\\Hostnames", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_statusKey, NULL ); check_noerr( err ); } CRegistrationPage::~CRegistrationPage() { if ( m_hostnameSetupKey ) { RegCloseKey( m_hostnameSetupKey ); m_hostnameSetupKey = NULL; } if ( m_registrationSetupKey ) { RegCloseKey( m_registrationSetupKey ); m_registrationSetupKey = NULL; } if ( m_statusKey ) { RegCloseKey( m_statusKey ); m_statusKey = NULL; } } //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::DoDataExchange //--------------------------------------------------------------------------------------------------------------------------- void CRegistrationPage::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CRegistrationPage) //}}AFX_DATA_MAP DDX_Control(pDX, IDC_HOSTNAME, m_hostnameControl); DDX_Control(pDX, IDC_USERNAME, m_usernameControl); DDX_Control(pDX, IDC_PASSWORD, m_passwordControl); DDX_Control(pDX, IDC_ADVERTISE_SERVICES, m_advertiseServices); } BEGIN_MESSAGE_MAP(CRegistrationPage, CPropertyPage) //{{AFX_MSG_MAP(CRegistrationPage) //}}AFX_MSG_MAP ON_EN_CHANGE(IDC_HOSTNAME, OnEnChangeHostname) ON_EN_CHANGE(IDC_USERNAME, OnEnChangeUsername) ON_EN_CHANGE(IDC_PASSWORD, OnEnChangePassword) ON_BN_CLICKED(IDC_ADVERTISE_SERVICES, OnBnClickedAdvertiseServices) END_MESSAGE_MAP() //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::OnEnChangedHostname //--------------------------------------------------------------------------------------------------------------------------- void CRegistrationPage::OnEnChangeHostname() { if ( !m_ignoreChanges ) { SetModified( TRUE ); } } //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::OnEnChangedUsername //--------------------------------------------------------------------------------------------------------------------------- void CRegistrationPage::OnEnChangeUsername() { if ( !m_ignoreChanges ) { SetModified( TRUE ); } } //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::OnEnChangedPassword //--------------------------------------------------------------------------------------------------------------------------- void CRegistrationPage::OnEnChangePassword() { if ( !m_ignoreChanges ) { SetModified( TRUE ); } } //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::OnBnClickedAdvertiseServices //--------------------------------------------------------------------------------------------------------------------------- void CRegistrationPage::OnBnClickedAdvertiseServices() { if ( !m_ignoreChanges ) { SetModified( TRUE ); } } //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::SetModified //--------------------------------------------------------------------------------------------------------------------------- void CRegistrationPage::SetModified( BOOL bChanged ) { m_modified = bChanged ? true : false; CPropertyPage::SetModified( bChanged ); } //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::OnSetActive //--------------------------------------------------------------------------------------------------------------------------- BOOL CRegistrationPage::OnSetActive() { TCHAR name[kDNSServiceMaxDomainName + 1]; DWORD nameLen = ( kDNSServiceMaxDomainName + 1 ) * sizeof( TCHAR ); DWORD err; BOOL b = CPropertyPage::OnSetActive(); m_ignoreChanges = true; m_modified = FALSE; if ( m_hostnameSetupKey ) { err = RegQueryValueEx( m_hostnameSetupKey, L"", NULL, NULL, (LPBYTE) name, &nameLen ); if ( !err ) { char hostnameUTF8[ 256 ]; char outDomain[ 256 ]; char outUsername[ 256 ]; char outPassword[ 256 ]; CString hostname = name; CString username; CString password; m_hostnameControl.SetWindowText( hostname ); StringObjectToUTF8String( hostname, hostnameUTF8, sizeof( hostnameUTF8 ) ); if ( LsaGetSecret( hostnameUTF8, outDomain, sizeof( outDomain ) / sizeof( TCHAR ), outUsername, sizeof( outUsername ) / sizeof( TCHAR ), outPassword, sizeof( outPassword ) / sizeof( TCHAR ) ) ) { username = outUsername; m_usernameControl.SetWindowText( username ); password = outPassword; m_passwordControl.SetWindowText( password ); } } } m_advertiseServices.SetCheck( 0 ); if ( m_registrationSetupKey ) { HKEY subKey = NULL; DWORD dwSize; DWORD enabled = 0; TCHAR subKeyName[MAX_KEY_LENGTH]; DWORD cSubKeys = 0; DWORD cbMaxSubKey; DWORD cchMaxClass; OSStatus err; err = RegQueryInfoKey( m_registrationSetupKey, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL ); if ( !err ) { if ( cSubKeys > 0 ) { dwSize = MAX_KEY_LENGTH; err = RegEnumKeyEx( m_registrationSetupKey, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL ); if ( !err ) { err = RegOpenKey( m_registrationSetupKey, subKeyName, &subKey ); if ( !err ) { dwSize = sizeof( DWORD ); err = RegQueryValueEx( subKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize ); if ( !err && enabled ) { m_advertiseServices.SetCheck( enabled ); } RegCloseKey( subKey ); subKey = NULL; } } } } } m_ignoreChanges = false; return b; } //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::OnOK //--------------------------------------------------------------------------------------------------------------------------- void CRegistrationPage::OnOK() { if ( m_modified ) { Commit(); } } //--------------------------------------------------------------------------------------------------------------------------- // CRegistrationPage::Commit //--------------------------------------------------------------------------------------------------------------------------- void CRegistrationPage::Commit() { CString hostname; char hostnameUTF8[ 256 ]; CString username; char usernameUTF8[ 256 ]; CString password; char passwordUTF8[ 256 ]; DWORD enabled = 1; BOOL secret = FALSE; DWORD err; m_hostnameControl.GetWindowText( hostname ); hostname.MakeLower(); hostname.TrimRight( '.' ); StringObjectToUTF8String( hostname, hostnameUTF8, sizeof( hostnameUTF8 ) ); m_usernameControl.GetWindowText( username ); m_passwordControl.GetWindowText( password ); if ( username.GetLength() && password.GetLength() ) { StringObjectToUTF8String( username, usernameUTF8, sizeof( usernameUTF8 ) ); StringObjectToUTF8String( password, passwordUTF8, sizeof( passwordUTF8 ) ); secret = TRUE; } if ( m_hostnameSetupKey != NULL ) { err = RegSetValueEx( m_hostnameSetupKey, L"", 0, REG_SZ, (LPBYTE) (LPCTSTR) hostname, ( hostname.GetLength() + 1 ) * sizeof( TCHAR ) ); require_noerr( err, exit ); err = RegSetValueEx( m_hostnameSetupKey, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) ); require_noerr( err, exit ); if ( secret ) { LsaSetSecret( hostnameUTF8, usernameUTF8, passwordUTF8 ); } } if ( m_registrationSetupKey != NULL ) { TCHAR subKeyName[MAX_KEY_LENGTH]; DWORD cSubKeys = 0; DWORD cbMaxSubKey; DWORD cchMaxClass; DWORD dwSize; int i; OSStatus err = kNoErr; // First, remove all the entries that are there err = RegQueryInfoKey( m_registrationSetupKey, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL ); if ( !err ) { for ( i = 0; i < (int) cSubKeys; i++ ) { dwSize = MAX_KEY_LENGTH; err = RegEnumKeyEx( m_registrationSetupKey, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL ); require_noerr( err, exit ); err = RegDeleteKey( m_registrationSetupKey, subKeyName ); require_noerr( err, exit ); } } if ( m_advertiseServices.GetCheck() ) { const char * domainUTF8; CString domain; char label[ 64 ]; HKEY subKey = NULL; domainUTF8 = GetNextLabel( hostnameUTF8, label ); domain = domainUTF8; err = RegCreateKeyEx( m_registrationSetupKey, domain, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &subKey, NULL ); if ( !err ) { err = RegSetValueEx( subKey, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) ); check_noerr( err ); RegCloseKey( subKey ); subKey = NULL; } if ( secret ) { LsaSetSecret( domainUTF8, usernameUTF8, passwordUTF8 ); } } } exit: return; }