|
|
//--------------------------------------------------------------------------
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif
// Windows Header Files:
#include <windows.h>
#include <sddl.h>
#include <setupapi.h>
#include <lmcons.h>
#include "ocmanage.h"
#include "uddiocm.h"
#include "uddiinst.h"
#include "assert.h"
#include "..\shared\common.h"
#include "resource.h"
#include "objectpicker.h"
#include <shlobj.h>
#include <ntsecapi.h>
#include <iiscnfg.h> // MD_ & IIS_MD_ defines
#ifndef MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM
#define MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM 0
#define MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE 1
#define MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE 2
#define MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER 3
#endif
#define NOT_FIRST_OR_LAST_WIZARD_PAGE false
#define FINAL_WIZARD_PAGE true
#define WELCOME_WIZARD_PAGE true
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS 0
#endif
//--------------------------------------------------------------------------
#define PASSWORD_LEN PWLEN // maximum password length
#define USERNAME_LEN UNLEN // maximum user name length
#define UDDI_MAXPROVNAME_LEN 255 // maximum UDDI Business Entity name length
#define UDDI_ILLEGALNAMECHARS TEXT( "\":;/\\?*" )
extern HINSTANCE g_hInstance; extern CUDDIInstall g_uddiComponents;
static CDBInstance g_dbLocalInstances; static CDBInstance g_dbRemoteInstances; static HWND g_hPropSheet = NULL ; static HFONT g_hTitleFont = 0; static TCHAR g_szPwd[ PASSWORD_LEN + 1 ];
//
// "allowed" drive letters for a clustered environment scenario.
// Not used for a "regular" installation
//
static CLST_ALLOWED_DRIVES gAllowedClusterDrives;
//
// This controls whether the Data Paths page will be shown in "simple" mode by default
//
static BOOL g_bSimpleDatapathUI = TRUE; static BOOL g_bResetPathFields = FALSE;
//
// This controls whether we do clustering data collection. This variable is used
// to coordinate operation between pages
//
static BOOL g_bSkipClusterAnalysis = FALSE; static BOOL g_bOnActiveClusterNode = TRUE; static BOOL g_bPreserveDatabase = FALSE;
static int DisplayUDDIErrorDialog( HWND hDlg, UINT uMsgID, UINT uType = MB_OK | MB_ICONWARNING, DWORD dwError = 0 ); static void ParseUserAccount( PTCHAR szDomainAndUser, UINT uDomainAndUserSize, PTCHAR szUser, UINT uUserSize, PTCHAR szDomain, UINT uDomainSize, bool &bLocalAccount ); static BOOL GetWellKnownAccountName( WELL_KNOWN_SID_TYPE sidWellKnown, TCHAR *pwszName, DWORD *pcbSize );
BOOL ShowBrowseDirDialog( HWND hParent, LPCTSTR szTitle, LPTSTR szOutBuf ); int CALLBACK BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData );
static BOOL GrantNetworkLogonRights( LPCTSTR pwszDomainUser ); //--------------------------------------------------------------------------
INT_PTR CALLBACK LocalDBInstanceDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK RemoteDBInstanceDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK SSLDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK ProviderInstanceDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK AddSvcDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK LoginDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK WizardSummaryDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK DataPathsDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK ExistingDBInstanceProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK ClusterDataDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK ConfirmPasswordDlgProc( HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam );
//--------------------------------------------------------------------------
static int DisplayUDDIErrorDialog( HWND hDlg, UINT uMsgID, UINT uType, DWORD dwError ) { TCHAR szMsg[ 1000 ]; TCHAR szTitle[ 100 ];
LoadString( g_hInstance, uMsgID, szMsg, sizeof( szMsg ) / sizeof( TCHAR ) ); LoadString( g_hInstance, IDS_TITLE, szTitle, sizeof( szTitle ) / sizeof( TCHAR ) ); tstring cMsg = szMsg;
if( dwError ) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, 0, NULL );
//
// FIX: 718923: this used to throw an exception if lpMsgBuf was NULL
//
if( lpMsgBuf ) { if ( cMsg.length() > 0 ) cMsg.append( TEXT( " " ) );
cMsg.append( (LPTSTR) lpMsgBuf ); LocalFree( lpMsgBuf ); } }
return MessageBox( hDlg, cMsg.c_str(), szTitle, uType ); }
//--------------------------------------------------------------------------
inline int SkipWizardPage( const HWND hdlg ) { SetWindowLongPtr( hdlg, DWLP_MSGRESULT, -1 ); return 1; //Must return 1 for the page to be skipped
}
//--------------------------------------------------------------------------
static HPROPSHEETPAGE CreatePage( const int nID, const DLGPROC pDlgProc, const PTCHAR szTitle, const PTCHAR szSubTitle, bool bFirstOrLast ) { PROPSHEETPAGE Page; memset( &Page, 0, sizeof( PROPSHEETPAGE ) );
Page.dwSize = sizeof( PROPSHEETPAGE ); Page.dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE | PSP_USETITLE; // use PSP_USETITLE without specifying szTitle to keep from overwriting the default propery page title
if ( bFirstOrLast ) { Page.dwFlags |= PSP_HIDEHEADER; } Page.hInstance = ( HINSTANCE )g_hInstance; Page.pszTemplate = MAKEINTRESOURCE( nID ); Page.pfnDlgProc = pDlgProc; Page.pszHeaderTitle = _tcsdup( szTitle ); Page.pszHeaderSubTitle = _tcsdup( szSubTitle );
HPROPSHEETPAGE PageHandle = CreatePropertySheetPage( &Page );
return PageHandle; }
//--------------------------------------------------------------------------
DWORD AddUDDIWizardPages( const TCHAR *ComponentId, const WizardPagesType WhichOnes, SETUP_REQUEST_PAGES *SetupPages ) { ENTER();
HPROPSHEETPAGE pPage = NULL; DWORD iPageIndex = 0 ;
TCHAR szTitle[ 256 ]; TCHAR szSubtitle[ 256 ]; LoadString( g_hInstance, IDS_TITLE, szTitle, sizeof( szTitle ) / sizeof( TCHAR ) );
//
// only add our pages when the OCM asks for the "Late Pages"
//
if( WizPagesLate == WhichOnes ) { if( SetupPages->MaxPages < 9 ) return 9;
//
// add the local db instance selection page
//
LoadString( g_hInstance, IDS_DB_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_DB_INSTANCE, LocalDBInstanceDlgProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_DB_INSTANCE Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the hidden clustering "data collector" page
//
pPage = CreatePage( IDD_CLUSTDATA, ClusterDataDlgProc, TEXT( "" ), TEXT( "" ), NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_CLUSTDATA Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the "uddi instance found" info page
//
LoadString( g_hInstance, IDS_EXISTINGDB_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_EXISTING_DBINSTANCE, ExistingDBInstanceProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_EXISTING_DBINSTANCE Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the SSL page
//
LoadString( g_hInstance, IDS_SSL_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_SSL, SSLDlgProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_SSL Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the remote db instance selection page
//
LoadString( g_hInstance, IDS_REMOTE_DB_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_REMOTE_DB, RemoteDBInstanceDlgProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_REMOTE_DB Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the data file path(s) selection page
//
LoadString( g_hInstance, IDS_FILEPATHS_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_DATAPATHS, DataPathsDlgProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_DATAPATHS Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the authentication page
//
LoadString( g_hInstance, IDS_LOGIN_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_LOGIN, LoginDlgProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_LOGIN Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the UDDI Provider Name page
//
LoadString( g_hInstance, IDS_UDDIPROV_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_SITE_NAME, ProviderInstanceDlgProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_SITE_NAME Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the UDDI "Add Service / Update AD"
//
LoadString( g_hInstance, IDS_UDDIADDSVC_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_ADD_SERVICES, AddSvcDlgProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_ADD_SERVICES Property Page" ) ); return( (DWORD)( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++;
//
// add the wizard summary page
//
/*
LoadString( g_hInstance, IDS_WIZARD_SUMMARY_SUBTITLE, szSubtitle, sizeof( szSubtitle ) / sizeof( TCHAR ) ); pPage = CreatePage( IDD_WIZARD_SUMMARY, WizardSummaryDlgProc, szTitle, szSubtitle, NOT_FIRST_OR_LAST_WIZARD_PAGE ); //pPage = CreatePage( IDD_WIZARD_SUMMARY, WizardSummaryDlgProc, szTitle, szSubtitle, FINAL_WIZARD_PAGE );
if ( NULL == pPage ) { Log( TEXT( "***Unable to add the IDD_LOGIN Property Page" ) ); return( ( DWORD )( -1 ) ); }
SetupPages->Pages[iPageIndex] = pPage; iPageIndex++; */ }
return iPageIndex; }
//--------------------------------------------------------------------------
INT_PTR CALLBACK LocalDBInstanceDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: { //
// start off with MSDE to not install
//
g_uddiComponents.SetInstallLevel( UDDI_MSDE, UDDI_NOACTION );
//
// get a handle to the list box
//
HWND hwndList = GetDlgItem( hDlg, IDC_LIST_DB_INSTANCES );
//
// Get the list of SQL 2000 ( only ) database instances and, if any are found, populate the list box
//
LONG iRet = g_dbLocalInstances.GetInstalledDBInstanceNames(); if( ERROR_SUCCESS == iRet ) { TCHAR szBuffer[ 50 ]; for( int i = 0; i < g_dbLocalInstances.GetInstanceCount(); i++ ) { if( g_dbLocalInstances.GetInstanceName( i, szBuffer, 50 ) ) { DWORD iIndex = (DWORD) SendMessage( hwndList, CB_ADDSTRING, 0, (LPARAM)szBuffer ); SendMessage( hwndList, CB_SETITEMDATA, (WPARAM) iIndex, (LPARAM)i ); } } }
//
// Is SQL on this box?
//
if( g_dbLocalInstances.GetInstanceCount() > 0 ) { //
// select the SQL radio button
//
CheckRadioButton( hDlg, IDC_RADIO_INSTALL_MSDE, IDC_RADIO_USE_EXISTING_INSTANCE, IDC_RADIO_USE_EXISTING_INSTANCE );
//
// is there an instance named "UDDI" on this machine?
//
// If NO, then select the 1st entry in the combo box.
//
// If YES, then select the "UDDI" entry from the combo box. Also, disable
// the option to select MSDE.
//
// FIX: 763442 There was a problem with the test to determine if a SQL Instance named
// "UDDI" was installed.
//
// BUGBUG:CREEVES This function is named improperly Is...() should return a bool
//
if( g_dbLocalInstances.IsInstanceInstalled( UDDI_MSDE_INSTANCE_NAME ) >= 0 ) { //
// Found a SQL Instance named "UDDI"
//
//
// Disable the MSDE radio, as there is another UDDI instance found
//
EnableWindow( GetDlgItem( hDlg, IDC_RADIO_INSTALL_MSDE ), false ); SendMessage( hwndList, CB_SETCURSEL, 0, 0 ); } else { //
// A SQL Instance named "UDDI" was not found
//
SendMessage( hwndList, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) UDDI_MSDE_INSTANCE_NAME ); } } else { //
// there are no sql instances on this machine
// disable the SQL radio button and list box
//
EnableWindow( GetDlgItem( hDlg, IDC_LIST_DB_INSTANCES ), false ); EnableWindow( GetDlgItem( hDlg, IDC_RADIO_USE_EXISTING_INSTANCE ), false ); //
// select the MSDE radio button
//
CheckRadioButton( hDlg, IDC_RADIO_INSTALL_MSDE, IDC_RADIO_USE_EXISTING_INSTANCE, IDC_RADIO_INSTALL_MSDE ); }
//
// find out if our instance of MSDE ( SqlRun08.msi ) is already used on this machine
//
bool bIsSqlRun08AlreadyUsed = false; if( !IsSQLRun08AlreadyUsed( &bIsSqlRun08AlreadyUsed ) ) { Log( TEXT( "IsSQLRun08AlreadyUsed() failed" ) ); break; }
if( bIsSqlRun08AlreadyUsed ) { //
// MSDE is already installed, so disable the MSDE radio button
//
EnableWindow( GetDlgItem( hDlg, IDC_RADIO_INSTALL_MSDE ), false ); } else { //
// MSDE is NOT on this box, but before we select the MSDE radio button
// we want to see if there is a SQL instance named UDDI,
// if so we'll make that the default.
//
if( -1 == g_dbLocalInstances.IsInstanceInstalled( UDDI_MSDE_INSTANCE_NAME ) ) { CheckRadioButton( hDlg, IDC_RADIO_INSTALL_MSDE, IDC_RADIO_USE_EXISTING_INSTANCE, IDC_RADIO_INSTALL_MSDE ); } }
//
// enable/disable the list box
//
EnableWindow( GetDlgItem( hDlg, IDC_LIST_DB_INSTANCES ), IsDlgButtonChecked( hDlg, IDC_RADIO_USE_EXISTING_INSTANCE ) ); } break;
case WM_COMMAND:
//
// someone clicked a radio button:
//
if( LOWORD( wParam ) == IDC_RADIO_INSTALL_MSDE || LOWORD( wParam ) == IDC_RADIO_USE_EXISTING_INSTANCE ) { if( HIWORD( wParam ) == BN_CLICKED ) { // disable the list box if its radio button is not clicked
EnableWindow( GetDlgItem( hDlg, IDC_LIST_DB_INSTANCES ), IsDlgButtonChecked( hDlg, IDC_RADIO_USE_EXISTING_INSTANCE ) ); } } break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { //
// this page needed only if we are installing the DB
//
g_uddiComponents.UpdateAllInstallLevel();
//
// Set the flag for ClusterDataProc so that when the user clicks "Next"
// it won't skip the data collection step
//
g_bSkipClusterAnalysis = FALSE;
if( g_uddiComponents.IsInstalling( UDDI_DB ) ) { PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } else { return SkipWizardPage( hDlg ); } }
//
// this message is sent when the user presses the "next" button
//
case PSN_WIZNEXT: { //
// are we installing MSDE?
//
bool bInstallMSDE = ( BST_CHECKED == IsDlgButtonChecked( hDlg, IDC_RADIO_INSTALL_MSDE ) ); if( bInstallMSDE ) { //
// check to see if SqlRun08 is already on this box
//
bool bIsSqlRun08AlreadyUsed = false; IsSQLRun08AlreadyUsed( &bIsSqlRun08AlreadyUsed ); if( bIsSqlRun08AlreadyUsed ) { DisplayUDDIErrorDialog( hDlg, IDS_MSDE_ALREADY_USED ); SetWindowLongPtr( hDlg,DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
//
// set the MSDE instance name to "UDDI"
//
g_uddiComponents.SetDBInstanceName( UDDI_LOCAL_COMPUTER, UDDI_MSDE_INSTANCE_NAME, UDDI_INSTALLING_MSDE, false );
//
// set MSDE to install
//
g_uddiComponents.SetInstallLevel( UDDI_MSDE, UDDI_INSTALL, TRUE );
//
// exit this property page
//
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; // done
} //
// we are using an existing instance of SQL
//
else { //
// get a handle to the combobox
//
HWND hwndList = GetDlgItem( hDlg, IDC_LIST_DB_INSTANCES );
//
// get the index of the string that is currently selected in the combobox
//
int nItem = ( int ) SendMessage( hwndList, CB_GETCURSEL, 0, 0 ); //
// if no string is selected, raise an error
//
if( CB_ERR == nItem ) { DisplayUDDIErrorDialog( hDlg, IDS_NO_INSTANCE_MSG ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
//
// get the index into the instance array of the selected item
//
int nInstanceIndex = ( int ) SendMessage( hwndList, CB_GETITEMDATA, nItem, ( LPARAM ) 0 );
//
// Now verify that the selected instance meets our requirements
//
if( CompareVersions( g_dbLocalInstances.m_dbinstance[ nInstanceIndex ].cSPVersion.c_str(), MIN_SQLSP_VERSION ) < 0 ) { DisplayUDDIErrorDialog( hDlg, IDS_SQLSPVERSION_TOO_LOW ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
//
// set the instance name
//
g_uddiComponents.SetDBInstanceName( g_dbLocalInstances.m_dbinstance[ nInstanceIndex ].cComputerName.c_str(), g_dbLocalInstances.m_dbinstance[ nInstanceIndex ].cSQLInstanceName.c_str(), UDDI_NOT_INSTALLING_MSDE, g_dbLocalInstances.m_dbinstance[ nInstanceIndex ].bIsCluster );
//
// Set MSDE to NOT INSTALL
//
g_uddiComponents.SetInstallLevel( UDDI_MSDE, UDDI_NOACTION );
//
// exit this property page
//
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; // done
} }
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//--------------------------------------------------------------------------
INT_PTR CALLBACK SSLDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: //
// turn SSL on by default
//
CheckRadioButton( hDlg, IDC_SSL_YES, IDC_SSL_NO, IDC_SSL_YES ); break;
case WM_COMMAND: break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { //
// this page needed only if we are installing the DB
//
g_uddiComponents.UpdateAllInstallLevel(); if( g_uddiComponents.IsInstalling( UDDI_DB ) && g_bOnActiveClusterNode && !g_bPreserveDatabase ) { PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } else { return SkipWizardPage( hDlg ); } }
case PSN_WIZNEXT: { //
// set the SSL mode by adding a property to the DB setup command line
//
bool bUseSSL = ( BST_CHECKED == IsDlgButtonChecked( hDlg, IDC_SSL_YES ) ); g_uddiComponents.AddProperty( UDDI_DB, TEXT( "SSL" ), bUseSSL ? 1 : 0 );
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; }
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//
//--------------------------------------------------------------------------
//
INT_PTR CALLBACK ProviderInstanceDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: //
// set the maximum edit field length
//
SendMessage( GetDlgItem( hDlg, IDC_SITE_NAME ), EM_LIMITTEXT, ( WPARAM ) UDDI_MAXPROVNAME_LEN, 0 ); break;
case WM_COMMAND: break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { //
// this page needed only if we are installing the DB
//
g_uddiComponents.UpdateAllInstallLevel(); if( g_uddiComponents.IsInstalling( UDDI_DB ) && g_bOnActiveClusterNode && !g_bPreserveDatabase ) { PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } else { return SkipWizardPage( hDlg ); } }
case PSN_WIZNEXT: { //
// set the Provider Instance Name by adding a property to the DB setup command line
//
TCHAR buf[ UDDI_MAXPROVNAME_LEN + 1 ]; ZeroMemory( buf, sizeof buf ); int iChars = GetWindowText( GetDlgItem( hDlg, IDC_SITE_NAME ), buf, ( sizeof( buf ) / sizeof( buf[0] ) ) -1 ); if( 0 == iChars ) { DisplayUDDIErrorDialog( hDlg, IDS_ZERO_LEN_PROVIDER_NAME ); SetFocus( GetDlgItem( hDlg, IDC_SITE_NAME ) ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
//
// Now verify that the instance name does not contain illegal characters
//
TCHAR *pIllegalChar = _tcspbrk( buf, UDDI_ILLEGALNAMECHARS ); if ( pIllegalChar ) { DisplayUDDIErrorDialog( hDlg, IDS_UDDI_ILLEGALCHARACTERS ); SetFocus( GetDlgItem( hDlg, IDC_SITE_NAME ) ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_UDDIPROVIDER, buf );
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; }
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//
//-----------------------------------------------------------------------------------
//
void ToggleDatapathUI ( HWND hDlg, BOOL bToSimple ) { TCHAR szBuf[ 256 ];
if ( bToSimple ) { //
// Hide fields
//
ShowWindow( GetDlgItem( hDlg, IDC_COREPATH_1 ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_COREPATH_2 ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_JRNLPATH ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_STAGINGPATH ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_XLOGPATH ), SW_HIDE );
//
// Hide buttons
//
ShowWindow( GetDlgItem( hDlg, IDC_BROWSECOREPATH1 ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSECOREPATH2 ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSEJRNLPATH ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSESTAGINGPATH ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSEXLOGPATH ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_LESS_BTN ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_MORE_BTN ), SW_SHOW );
//
// Hide labels and adjust the text
//
ShowWindow( GetDlgItem( hDlg, IDC_STATIC_C1 ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_STATIC_C2 ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_STATIC_JRNL ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_STATIC_STG ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_STATIC_XLOG ), SW_HIDE ); LoadString( g_hInstance, IDS_LABEL_SYSPATHSIMPLE, szBuf, (sizeof szBuf / sizeof szBuf[0]) - 1 ); SetDlgItemText( hDlg, IDC_STATIC_SYS, szBuf ); } else { //
// Show fields
//
ShowWindow( GetDlgItem( hDlg, IDC_COREPATH_1 ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_COREPATH_2 ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_JRNLPATH ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_STAGINGPATH ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_XLOGPATH ), SW_SHOW );
//
// Show buttons
//
ShowWindow( GetDlgItem( hDlg, IDC_MORE_BTN ), SW_HIDE ); ShowWindow( GetDlgItem( hDlg, IDC_LESS_BTN ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSECOREPATH1 ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSECOREPATH2 ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSEJRNLPATH ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSESTAGINGPATH ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_BROWSEXLOGPATH ), SW_SHOW ); //
// Show labels and adjust the text
//
ShowWindow( GetDlgItem( hDlg, IDC_STATIC_C1 ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_STATIC_C2 ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_STATIC_JRNL ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_STATIC_STG ), SW_SHOW ); ShowWindow( GetDlgItem( hDlg, IDC_STATIC_XLOG ), SW_SHOW );
LoadString( g_hInstance, IDS_LABEL_SYSPATH_ADV, szBuf, (sizeof szBuf / sizeof szBuf[0]) - 1 ); SetDlgItemText( hDlg, IDC_STATIC_SYS, szBuf ); } }
void SetAllDatapathFields ( HWND hDlg, LPCTSTR szValue ) { SetDlgItemText( hDlg, IDC_SYSPATH, szValue ); SetDlgItemText( hDlg, IDC_COREPATH_1, szValue ); SetDlgItemText( hDlg, IDC_COREPATH_2, szValue ); SetDlgItemText( hDlg, IDC_JRNLPATH, szValue ); SetDlgItemText( hDlg, IDC_STAGINGPATH, szValue ); SetDlgItemText( hDlg, IDC_XLOGPATH, szValue ); }
INT_PTR CALLBACK ClusterDataDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { bool bSuppressInactiveWarning = false;
//
// We ALWAYS skip the page, but if this is a DB installation, then we
// also need to do some data collection here
//
g_uddiComponents.UpdateAllInstallLevel(); if( !g_bSkipClusterAnalysis ) { //
// Here we do our cluster environment checks
//
gAllowedClusterDrives.driveCount = 0; g_bOnActiveClusterNode = TRUE; //
// Make sure we keep out installation properties in sync with the
// cluster configuration
//
g_uddiComponents.DeleteProperty( UDDI_DB, PROPKEY_CLUSTERNODETYPE ); g_uddiComponents.DeleteProperty( UDDI_WEB, PROPKEY_CLUSTERNODETYPE );
if ( g_uddiComponents.IsClusteredDBInstance() ) { //
// First, try connecting to the database
// If the database already exists, then just leave it
// intact and skip the drive enumeration process
//
TCHAR szVerBuf[ 256 ] = {0}; size_t cbVerBuf = DIM( szVerBuf ) - 1;
HCURSOR hcrHourglass = LoadCursor( NULL, IDC_WAIT ); HCURSOR hcrCurr = SetCursor( hcrHourglass );
HRESULT hr = GetDBSchemaVersion( g_uddiComponents.GetFullDBInstanceName(), szVerBuf, cbVerBuf );
SetCursor( hcrCurr );
if ( SUCCEEDED( hr ) && _tcslen( szVerBuf ) ) { g_bPreserveDatabase = TRUE; int iRes = DisplayUDDIErrorDialog( hDlg, IDS_DB_EXISTS, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 ); if ( iRes == IDNO ) { // force user to the instance selection page
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, IDD_DB_INSTANCE ); return 1; }
bSuppressInactiveWarning = true; } else { g_bPreserveDatabase = FALSE; }
cDrvMap::size_type nDrivesFound = 0;
HCLUSTER hCls = OpenCluster( NULL ); if ( !hCls ) { DisplayUDDIErrorDialog( hDlg, IDS_CANTOPENCLUSTER ); // force user to the previous page
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, IDD_DB_INSTANCE ); return 1; }
hcrCurr = SetCursor( hcrHourglass );
//
// now we will format the instance name and collect the data
//
try { TCHAR szComputerName[ 256 ] = {0}; WCHAR szNode[ 256 ] = {0}; DWORD dwErr = ERROR_SUCCESS; DWORD cbComputerName = DIM( szComputerName ); DWORD cbNode = DIM( szNode ); cStrList cDependencies; cDrvMap cPhysicalDrives;
tstring sServerName = g_uddiComponents.GetDBComputerName(); tstring sInstance = g_uddiComponents.GetDBInstanceName();
if ( !_tcsicmp( sInstance.c_str(), DEFAULT_SQL_INSTANCE_NAME ) ) sInstance = DEFAULT_SQL_INSTANCE_NATIVE;
sServerName += TEXT( "\\" ); sServerName += sInstance;
dwErr = GetSqlNode( sServerName.c_str(), szNode, cbNode ); if ( dwErr != ERROR_SUCCESS ) throw dwErr;
GetComputerName( szComputerName, &cbComputerName );
//
// Are we on the same node as the Sql server instance?
//
g_bOnActiveClusterNode = ( !_tcsicmp( szComputerName, szNode ) ); gAllowedClusterDrives.driveCount = 0;
//
// if we are installing database components,
// then we will need to go one step further and analyse
// the drive dependencies etc.
//
if ( g_bOnActiveClusterNode ) { if ( g_uddiComponents.IsInstalling( UDDI_DB ) && !g_bPreserveDatabase ) { //
// We are on an active (owning) node. Let's collect the drive data
//
dwErr = EnumSQLDependencies( hCls, &cDependencies, sServerName.c_str() ); if ( dwErr != ERROR_SUCCESS ) throw dwErr; dwErr = EnumPhysicalDrives( hCls, &cDependencies, &cPhysicalDrives ); if ( dwErr != ERROR_SUCCESS ) throw dwErr; int idx = 0; nDrivesFound = cPhysicalDrives.size(); if ( nDrivesFound == 0 ) { DisplayUDDIErrorDialog( hDlg, IDS_NOCLUSTERRESAVAIL ); // force user to the previous page
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, IDD_DB_INSTANCE ); return 1; }
//
// We are in an active node, make sure the user wants to continue
//
int iRes = DisplayUDDIErrorDialog( hDlg, IDS_ACTIVENODE_DB, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 ); if ( iRes == IDNO ) { // force user to the instance selection page
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, IDD_DB_INSTANCE ); return 1; }
for ( cDrvIterator it = cPhysicalDrives.begin(); it != cPhysicalDrives.end(); it++ ) { gAllowedClusterDrives.drives[ idx ] = it->second.sDriveLetter; idx++; } gAllowedClusterDrives.driveCount = idx; }
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_CLUSTERNODETYPE, PROPKEY_ACTIVENODE ); g_uddiComponents.AddProperty( UDDI_WEB, PROPKEY_CLUSTERNODETYPE, PROPKEY_ACTIVENODE ); } else { if ( g_uddiComponents.IsInstalling( UDDI_DB ) && !bSuppressInactiveWarning ) { //
// We are on a passive node. Make a note
//
int iRes = DisplayUDDIErrorDialog( hDlg, IDS_PASSIVENODE_DB, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 ); if ( iRes == IDNO ) { // force user to the instance selection page
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, IDD_DB_INSTANCE ); return 1; } }
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_CLUSTERNODETYPE, PROPKEY_PASSIVENODE ); g_uddiComponents.AddProperty( UDDI_WEB, PROPKEY_CLUSTERNODETYPE, PROPKEY_PASSIVENODE ); } } catch (...) { DisplayUDDIErrorDialog( hDlg, IDS_GENERALCLUSTERR ); // force user to the previous page (SSL)
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, IDD_SSL ); return 1; } CloseCluster( hCls ); SetCursor( hcrCurr );
//
// Finally, signal the next page that the data has changed
//
g_bResetPathFields = TRUE; } else { gAllowedClusterDrives.driveCount = -1; g_bPreserveDatabase = FALSE; }
//
// Finally, set the flag to indicate that the job is done
//
g_bSkipClusterAnalysis = TRUE; }
return SkipWizardPage( hDlg ); }
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
INT_PTR CALLBACK DataPathsDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { tstring sTmpString; BOOL bRes = FALSE; TCHAR szTmpPath[ MAX_PATH + 1 ]; TCHAR szTmpTitle[ 256 ];
switch( msg ) { case WM_INITDIALOG: //
// set the maximum edit field length
//
SendMessage( GetDlgItem( hDlg, IDC_SYSPATH ), EM_LIMITTEXT, ( WPARAM ) MAX_PATH, 0 ); SendMessage( GetDlgItem( hDlg, IDC_COREPATH_1 ), EM_LIMITTEXT, ( WPARAM ) MAX_PATH, 0 ); SendMessage( GetDlgItem( hDlg, IDC_COREPATH_2 ), EM_LIMITTEXT, ( WPARAM ) MAX_PATH, 0 ); SendMessage( GetDlgItem( hDlg, IDC_JRNLPATH ), EM_LIMITTEXT, ( WPARAM ) MAX_PATH, 0 ); SendMessage( GetDlgItem( hDlg, IDC_STAGINGPATH ), EM_LIMITTEXT, ( WPARAM ) MAX_PATH, 0 ); SendMessage( GetDlgItem( hDlg, IDC_XLOGPATH ), EM_LIMITTEXT, ( WPARAM ) MAX_PATH, 0 );
//
// are we in a clustered environment ?
//
if ( g_uddiComponents.IsClusteredDBInstance() ) { if ( gAllowedClusterDrives.driveCount > 0 ) { sTmpString = gAllowedClusterDrives.drives[ 0 ]; sTmpString += TEXT( "\\uddi\\data" ); } else { //
// falling back on a default data path. This should never happen,
// this is just a safety net for us
//
sTmpString = g_uddiComponents.GetDefaultDataPath(); } } else sTmpString = g_uddiComponents.GetDefaultDataPath();
//
// Set the fields
//
SetAllDatapathFields( hDlg, sTmpString.c_str() );
//
// now hide the controls and set the dialog into the default mode
//
if ( g_bSimpleDatapathUI ) ToggleDatapathUI( hDlg, TRUE ); else ToggleDatapathUI( hDlg, FALSE );
break;
case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDC_MORE_BTN: // toggle to the "advanced mode"
{ g_bSimpleDatapathUI = FALSE; ToggleDatapathUI( hDlg, FALSE ); } break;
case IDC_LESS_BTN: // toggle to the "simple mode"
{ g_bSimpleDatapathUI = TRUE; ToggleDatapathUI( hDlg, TRUE ); } break;
case IDC_BROWSESYSPATH: { LoadString( g_hInstance, IDS_PROMPT_SELSYSDATAPATH, szTmpTitle, sizeof szTmpTitle / sizeof szTmpTitle[0] ); bRes = ShowBrowseDirDialog( hDlg, szTmpTitle, szTmpPath ); if ( bRes ) { SetDlgItemText( hDlg, IDC_SYSPATH, szTmpPath ); if ( g_bSimpleDatapathUI ) SetAllDatapathFields( hDlg, szTmpPath ); }
break; }
case IDC_BROWSECOREPATH1: { LoadString( g_hInstance, IDS_PROMPT_SELCOREPATH_1, szTmpTitle, sizeof szTmpTitle / sizeof szTmpTitle[0] ); bRes = ShowBrowseDirDialog( hDlg, szTmpTitle, szTmpPath ); if ( bRes ) SetDlgItemText( hDlg, IDC_COREPATH_1, szTmpPath );
break; }
case IDC_BROWSECOREPATH2: { LoadString( g_hInstance, IDS_PROMPT_SELCOREPATH_2, szTmpTitle, sizeof szTmpTitle / sizeof szTmpTitle[0] ); bRes = ShowBrowseDirDialog( hDlg, szTmpTitle, szTmpPath ); if ( bRes ) SetDlgItemText( hDlg, IDC_COREPATH_2, szTmpPath );
break; }
case IDC_BROWSEJRNLPATH: { LoadString( g_hInstance, IDS_PROMPT_SELJRNLPATH, szTmpTitle, sizeof szTmpTitle / sizeof szTmpTitle[0] ); bRes = ShowBrowseDirDialog( hDlg, szTmpTitle, szTmpPath ); if ( bRes ) SetDlgItemText( hDlg, IDC_JRNLPATH, szTmpPath );
break; }
case IDC_BROWSESTAGINGPATH: { LoadString( g_hInstance, IDS_PROMPT_SELSTGPATH, szTmpTitle, sizeof szTmpTitle / sizeof szTmpTitle[0] ); bRes = ShowBrowseDirDialog( hDlg, szTmpTitle, szTmpPath ); if ( bRes ) SetDlgItemText( hDlg, IDC_STAGINGPATH, szTmpPath );
break; }
case IDC_BROWSEXLOGPATH: { LoadString( g_hInstance, IDS_PROMPT_SELXLOGPATH, szTmpTitle, sizeof szTmpTitle / sizeof szTmpTitle[0] ); bRes = ShowBrowseDirDialog( hDlg, szTmpTitle, szTmpPath ); if ( bRes ) SetDlgItemText( hDlg, IDC_XLOGPATH, szTmpPath );
break; }
default: break;
} break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { //
// this page needed only if we are installing the DB
//
g_uddiComponents.UpdateAllInstallLevel(); if( g_uddiComponents.IsInstalling( UDDI_DB ) && g_bOnActiveClusterNode && !g_bPreserveDatabase ) { PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 );
//
// Check whether we need to update the data path fileds
// due to a change in the clustering data
//
if ( g_bResetPathFields ) { if ( g_uddiComponents.IsClusteredDBInstance() ) { if ( gAllowedClusterDrives.driveCount > 0 ) { sTmpString = gAllowedClusterDrives.drives[ 0 ]; sTmpString += TEXT( "\\uddi\\data" ); } else // falling back on a default data path
{ sTmpString = g_uddiComponents.GetDefaultDataPath(); } } else sTmpString = g_uddiComponents.GetDefaultDataPath();
//
// Set the fields
//
SetAllDatapathFields( hDlg, sTmpString.c_str() ); }
g_bResetPathFields = FALSE;
return 1; } else { return SkipWizardPage( hDlg ); } }
case PSN_WIZNEXT: { //
// set the Provider Instance Name by adding a property to the DB setup command line
//
TCHAR buf[ MAX_PATH + 1 ]; ZeroMemory( buf, sizeof buf ); //
// System Data File path
//
GetWindowText( GetDlgItem( hDlg, IDC_SYSPATH ), buf, ( sizeof buf / sizeof buf[0] ) - 1 ); if ( _tcslen( buf ) && ( buf[ _tcslen( buf ) - 1 ] == TEXT( '\\' ) ) ) _tcscat( buf, TEXT( "\\" ) );
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_SYSPATH, buf ); ZeroMemory( buf, sizeof buf );
//
// Core Data File path #1
//
GetWindowText( GetDlgItem( hDlg, IDC_COREPATH_1 ), buf, ( sizeof( buf ) / sizeof( buf[0] ) ) -1 ); if ( _tcslen( buf ) && ( buf[ _tcslen( buf ) - 1 ] == TEXT( '\\' ) ) ) _tcscat( buf, TEXT( "\\" ) );
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_COREPATH_1, buf ); ZeroMemory( buf, sizeof buf );
//
// Core Data File path #2
//
GetWindowText( GetDlgItem( hDlg, IDC_COREPATH_2 ), buf, ( sizeof( buf ) / sizeof( buf[0] ) ) -1 ); if ( _tcslen( buf ) && ( buf[ _tcslen( buf ) - 1 ] == TEXT( '\\' ) ) ) _tcscat( buf, TEXT( "\\" ) );
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_COREPATH_2, buf ); ZeroMemory( buf, sizeof buf );
//
// Journal Data File path
//
GetWindowText( GetDlgItem( hDlg, IDC_JRNLPATH ), buf, ( sizeof( buf ) / sizeof( buf[0] ) ) -1 ); if ( _tcslen( buf ) && ( buf[ _tcslen( buf ) - 1 ] == TEXT( '\\' ) ) ) _tcscat( buf, TEXT( "\\" ) );
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_JRNLPATH, buf ); ZeroMemory( buf, sizeof buf );
//
// Staging Data File path
//
GetWindowText( GetDlgItem( hDlg, IDC_STAGINGPATH ), buf, ( sizeof( buf ) / sizeof( buf[0] ) ) -1 ); if ( _tcslen( buf ) && ( buf[ _tcslen( buf ) - 1 ] == TEXT( '\\' ) ) ) _tcscat( buf, TEXT( "\\" ) );
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_STGPATH, buf ); ZeroMemory( buf, sizeof buf );
//
// Xact Log File path
//
GetWindowText( GetDlgItem( hDlg, IDC_XLOGPATH ), buf, ( sizeof( buf ) / sizeof( buf[0] ) ) -1 ); if ( _tcslen( buf ) && ( buf[ _tcslen( buf ) - 1 ] == TEXT( '\\' ) ) ) _tcscat( buf, TEXT( "\\" ) );
g_uddiComponents.AddProperty( UDDI_DB, PROPKEY_XLOGPATH, buf ); ZeroMemory( buf, sizeof buf );
//
// Finally, we can leave the page
//
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; }
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//
//--------------------------------------------------------------------------
//
INT_PTR CALLBACK ExistingDBInstanceProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { TCHAR buf[ 1024 ]; ULONG cbBuf = ( sizeof buf / sizeof buf[0] ); bool bRes = false;
switch( msg ) { case WM_INITDIALOG: //
// set the database instance name field
//
ZeroMemory( buf, sizeof buf );
bRes = g_dbLocalInstances.GetUDDIDBInstanceName( NULL, buf, &cbBuf ); if ( bRes ) { if ( !_tcsstr( buf, TEXT( "\\") ) ) { //
// Add the machine name
//
TCHAR szMachineName[ MAX_COMPUTERNAME_LENGTH + 1 ]; DWORD dwLen = MAX_COMPUTERNAME_LENGTH + 1;
ZeroMemory (szMachineName, sizeof szMachineName ); if ( GetComputerName( szMachineName, &dwLen ) ) { TCHAR szTmp[ 1024 ];
_tcscpy( szTmp, szMachineName ); _tcscat( szTmp, TEXT( "\\" ) ); _tcscat( szTmp, buf ); _tcscpy( buf, szTmp ); }
} SetDlgItemText( hDlg, IDC_INSTANCENAME, buf ); } break;
case WM_COMMAND: break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { //
// this page needed only if we are installing the Web & DB is here
//
g_uddiComponents.UpdateAllInstallLevel(); if( g_uddiComponents.IsInstalled( UDDI_DB ) && !g_uddiComponents.IsUninstalling( UDDI_DB ) && g_uddiComponents.IsInstalling( UDDI_WEB ) ) { PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } else { return SkipWizardPage( hDlg ); } }
case PSN_WIZNEXT: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; }
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//
//--------------------------------------------------------------------------
//
INT_PTR CALLBACK AddSvcDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: //
// Check the Publish This Site checkbox
//
CheckDlgButton( hDlg, IDC_CHECK_ADDSVC, BST_CHECKED ); break;
case WM_COMMAND: break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { //
// this page needed only if we are installing the DB
//
g_uddiComponents.UpdateAllInstallLevel(); if( g_uddiComponents.IsInstalling( UDDI_WEB ) ) { PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } else { return SkipWizardPage( hDlg ); } }
case PSN_WIZNEXT: { //
// set the "Add Services" and "Update AD" flags by adding the installation properties
//
bool bChecked = ( BST_CHECKED == IsDlgButtonChecked( hDlg, IDC_CHECK_ADDSVC ) ); g_uddiComponents.AddProperty( UDDI_WEB, PROPKEY_ADDSERVICES, ( bChecked ? 1 : 0 ) ); g_uddiComponents.AddProperty( UDDI_WEB, PROPKEY_UPDATE_AD, ( bChecked ? 1 : 0 ) );
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; }
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//
//--------------------------------------------------------------------------
//
INT_PTR CALLBACK RemoteDBInstanceDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_COMMAND: if( LOWORD( wParam ) == IDC_BROWSE_MACHINES ) { //
// use the object picker to select the remote machine name
//
HRESULT hr; BOOL bIsStd = FALSE; TCHAR szComputerName[ 256 ] = {0};
if ( !ObjectPicker( hDlg, OP_COMPUTER, szComputerName, 256 ) ) break; // user pressed cancel
hr = IsStandardServer( szComputerName, &bIsStd ); if ( SUCCEEDED( hr ) && bIsStd ) { DisplayUDDIErrorDialog( hDlg, IDS_CANTCONNTOSTD, MB_OK | MB_ICONWARNING ); break; }
//
// write the machine name into the static text box, and them clear the combo box
//
SendMessage( GetDlgItem( hDlg, IDC_REMOTE_MACHINE ), WM_SETTEXT, 0, ( LPARAM ) szComputerName );
//
// find out if a UDDI database already exists on that remote machine
//
TCHAR szInstanceName[ 100 ]; ULONG uLen = 100; if( g_dbRemoteInstances.GetUDDIDBInstanceName( szComputerName, szInstanceName, &uLen ) ) { //
// write the db instance name into the static text box
//
SendMessage( GetDlgItem( hDlg, IDC_REMOTE_INSTANCE ), WM_SETTEXT, 0, ( LPARAM ) szInstanceName ); } else { //
// remote machine was not accessable or did not have any instances
//
DisplayUDDIErrorDialog( hDlg, IDS_UDDI_DB_NOT_EXIST, MB_OK | MB_ICONWARNING ); } } break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { //
// needed if user is installing web and NOT the db, or the db is not installed
//
g_uddiComponents.UpdateAllInstallLevel(); if( g_uddiComponents.IsInstalling( UDDI_WEB ) && !g_uddiComponents.IsInstalling( UDDI_DB ) && ( !g_uddiComponents.IsInstalled( UDDI_DB ) || g_uddiComponents.IsUninstalling( UDDI_DB ) ) ) { UINT osMask = g_uddiComponents.GetOSSuiteMask(); BOOL bAdv = ( osMask & VER_SUITE_DATACENTER ) || ( osMask & VER_SUITE_ENTERPRISE );
EnableWindow( GetDlgItem( hDlg, IDC_BROWSE_MACHINES ), bAdv );
PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg,DWLP_MSGRESULT,0 ); return 1; } else { return SkipWizardPage( hDlg ); } }
//
// this is called when the user presses "next"
//
case PSN_WIZNEXT: { //
// get the remote machine name from the edit control
//
TCHAR szComputerName[ 129 ]; UINT iChars = ( UINT ) SendMessage( GetDlgItem( hDlg, IDC_REMOTE_MACHINE ), WM_GETTEXT, 129, ( LPARAM ) szComputerName ); if( 0 == iChars ) { DisplayUDDIErrorDialog( hDlg, IDS_SELECT_REMOTE_COMPUTER ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
//
// get the index of the database instance selection in the combobox
//
TCHAR szRemoteDBInstance[ 100 ]; iChars = ( UINT ) SendMessage( GetDlgItem( hDlg, IDC_REMOTE_INSTANCE ), WM_GETTEXT, 100, ( LPARAM ) szRemoteDBInstance ); if( 0 == iChars ) { DisplayUDDIErrorDialog( hDlg, IDS_UDDI_DB_NOT_EXIST ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
//
// save the computer and instance name. As we are using a remote node here,
// we don't really care whether it is on cluster or not
//
g_uddiComponents.SetDBInstanceName( szComputerName, szRemoteDBInstance, UDDI_NOT_INSTALLING_MSDE, false );
//
// the web installer needs the remote machine name to properly add the login
//
g_uddiComponents.AddProperty( UDDI_WEB, TEXT( "REMOTE_MACHINE_NAME" ), szComputerName );
Log( TEXT( "User selected remote computer %s and database instance %s" ), szComputerName, szRemoteDBInstance );
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; // done
}
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//--------------------------------------------------------------------------
INT_PTR CALLBACK LoginDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: //
// set the limit of the length of the password
//
SendMessage( GetDlgItem( hDlg, IDC_PASSWORD ), EM_LIMITTEXT, ( WPARAM ) PASSWORD_LEN, 0 ); SendMessage( GetDlgItem( hDlg, IDC_USER_NAME ), EM_LIMITTEXT, ( WPARAM ) USERNAME_LEN, 0 ); break;
case WM_COMMAND: //
// user clicked a radio button:
//
if( LOWORD( wParam ) == IDC_RADIO_NETWORK_SERVICE || LOWORD( wParam ) == IDC_RADIO_DOMAIN_ACCT ) { if( HIWORD( wParam ) == BN_CLICKED ) { EnableWindow( GetDlgItem( hDlg, IDC_USER_NAME ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); EnableWindow( GetDlgItem( hDlg, IDC_USER_NAME_PROMPT ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); EnableWindow( GetDlgItem( hDlg, IDC_PASSWORD ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); EnableWindow( GetDlgItem( hDlg, IDC_PASSWORD_PROMPT ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); EnableWindow( GetDlgItem( hDlg, IDC_BROWSE_USERS ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); } } //
// if the user clicked the "Browse" button
//
else if( LOWORD( wParam ) == IDC_BROWSE_USERS ) { //
// use the object picker to select the user
//
TCHAR szDomainUser[ 256 ]; if ( !ObjectPicker( hDlg, OP_USER, szDomainUser, 256 ) ) break;
//
// write the machine name into the static text box
//
SendMessage( GetDlgItem( hDlg, IDC_USER_NAME ), WM_SETTEXT, 0, ( LPARAM ) szDomainUser );
} break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { //
// this page is needed only when the WEB is being installed
//
g_uddiComponents.UpdateAllInstallLevel(); if( g_uddiComponents.IsInstalling( UDDI_WEB ) ) { PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 );
bool bIsClustered = g_uddiComponents.IsClusteredDBInstance();
if( ( g_uddiComponents.IsInstalling( UDDI_DB ) || ( g_uddiComponents.IsInstalled( UDDI_DB ) && !g_uddiComponents.IsUninstalling( UDDI_DB ) ) ) && !bIsClustered ) { CheckRadioButton( hDlg, IDC_RADIO_NETWORK_SERVICE, IDC_RADIO_DOMAIN_ACCT, IDC_RADIO_NETWORK_SERVICE ); } //
// db is not on the local box, so disable the network service account option
//
else { CheckRadioButton( hDlg, IDC_RADIO_NETWORK_SERVICE, IDC_RADIO_DOMAIN_ACCT, IDC_RADIO_DOMAIN_ACCT ); EnableWindow( GetDlgItem( hDlg, IDC_RADIO_NETWORK_SERVICE ), FALSE ); SetFocus( GetDlgItem( hDlg, IDC_USER_NAME ) ); }
EnableWindow( GetDlgItem( hDlg, IDC_USER_NAME ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); EnableWindow( GetDlgItem( hDlg, IDC_USER_NAME_PROMPT ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); EnableWindow( GetDlgItem( hDlg, IDC_PASSWORD ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); EnableWindow( GetDlgItem( hDlg, IDC_PASSWORD_PROMPT ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); EnableWindow( GetDlgItem( hDlg, IDC_BROWSE_USERS ), IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) ); } else { return SkipWizardPage( hDlg ); }
return 1; }
//
// this is called when the user presses "next"
//
case PSN_WIZNEXT: { //
// Get ready for the SID-to-user name conversions
//
TCHAR szSidStr[ 1024 ]; TCHAR szRemote[ 1024 ]; TCHAR szRemoteUser[ 1024 ]; DWORD cbSidStr = sizeof szSidStr / sizeof szSidStr[0]; DWORD cbRemoteUser = sizeof szRemoteUser / sizeof szRemoteUser[0];
TCHAR szComputerName[ MAX_COMPUTERNAME_LENGTH + 1 ]; DWORD dwCompNameLen = MAX_COMPUTERNAME_LENGTH + 1; GetComputerName( szComputerName, &dwCompNameLen );
ZeroMemory( szRemote, sizeof szRemote );
if( NULL == g_uddiComponents.GetProperty( UDDI_WEB, TEXT( "REMOTE_MACHINE_NAME" ), szRemote ) ) { _tcscpy( szRemote, szComputerName ); }
//
// set the property that defines whether we are using "Network Service" or a "User Login"
//
bool bUserAcct = ( BST_CHECKED == IsDlgButtonChecked( hDlg, IDC_RADIO_DOMAIN_ACCT ) );
//
// set the properties that denotes a domain user
//
if( bUserAcct ) { TCHAR szDomainUser[ USERNAME_LEN + 1 ];
//
// verify the user name length > 0
//
int iChars = GetWindowText( GetDlgItem( hDlg, IDC_USER_NAME ), szDomainUser, sizeof( szDomainUser ) / sizeof( TCHAR ) ); if( 0 == iChars ) { DisplayUDDIErrorDialog( hDlg, IDS_ZERO_LEN_USER_NAME ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
//
// make the user retype the password
//
GetWindowText( GetDlgItem( hDlg, IDC_PASSWORD ), g_szPwd, sizeof( g_szPwd ) / sizeof( TCHAR ) );
INT_PTR iRet = DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_CONFIRM_PW ), hDlg, ConfirmPasswordDlgProc );
if( IDCANCEL == iRet ) { //
// user pressed Cancel to the confirm dialog
//
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
TCHAR szUser[ USERNAME_LEN + 1 ]; TCHAR szDomain[ 256 ]; DWORD cbDomain = sizeof( szDomain ) / sizeof( szDomain[0] ); bool bLocalAccount;
ZeroMemory( szUser, sizeof( szUser ) ); ZeroMemory( szDomain, sizeof( szDomain ) );
ParseUserAccount( szDomainUser, sizeof( szDomainUser ) / sizeof ( TCHAR ), szUser, sizeof( szUser ) / sizeof ( TCHAR ), szDomain, sizeof( szDomain ) / sizeof ( TCHAR ), bLocalAccount );
//
// try to login as this account
// if there is no domain name specified
// then assume local account
//
if ( bLocalAccount ) { _tcscpy( szDomain, TEXT( "." ) );
//
// are we on a cluster ?
//
if ( g_uddiComponents.IsClusteredDBInstance() ) { DisplayUDDIErrorDialog( hDlg, IDS_WRONGLOGONTYPE, MB_OK | MB_ICONWARNING, GetLastError() ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
} }
BOOL fLogonRights = GrantNetworkLogonRights( szDomainUser ); if( !fLogonRights ) { //
// FIX: 727877: needed error dialog
//
DisplayUDDIErrorDialog( hDlg, IDS_LOGIN_ERROR, MB_OK | MB_ICONWARNING, E_FAIL ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; }
HANDLE hToken = NULL; BOOL bIsGoodLogin = LogonUser( szUser, _tcslen( szDomain ) > 0 ? szDomain : NULL, g_szPwd, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken);
if( bIsGoodLogin ) { HRESULT hr = S_OK;
Log( _T( "LogonUser succeeded with %s." ), szDomainUser );
//
// FIX: 718923: needed to test connectivity with SQL server via impersonation and OLEDB call
//
//
// If we're not installing MSDE, then a database exists for us to check connectivity.
//
if( !g_uddiComponents.IsInstalling( UDDI_MSDE ) ) { //
// Only check this when we're not installing the db components (i.e. off-machine setup)
//
if( !g_uddiComponents.IsInstalling( UDDI_DB ) ) { HCURSOR hcrHourglass = LoadCursor( NULL, IDC_WAIT ); HCURSOR hcrCurr = SetCursor( hcrHourglass );
//
// If workgroup account, we need to give AddServiceAccount the workgroup account on the db server.
// Else, just pass the domain account.
//
tstring sServerName; if( bLocalAccount ) { sServerName = g_uddiComponents.GetDBComputerName(); sServerName += _T( "\\" ); sServerName += szUser; } else { sServerName = szDomainUser; }
Log( _T( "Before AddServiceAccount for user %s, instance %s." ), sServerName.c_str(), g_uddiComponents.GetFullDBInstanceName() );
//
// Add user to service account on db.
//
hr = AddServiceAccount( g_uddiComponents.GetFullDBInstanceName(), sServerName.c_str() );
if( SUCCEEDED( hr ) ) { if( ImpersonateLoggedOnUser( hToken ) ) { Log( _T( "Successfully impersonated user %s\\%s." ), szDomain, szUser);
TCHAR szVerBuf[ 256 ] = {0}; size_t cbVerBuf = DIM( szVerBuf ) - 1;
Log( _T( "Before GetDBSchemaVersion for instance %s." ), g_uddiComponents.GetFullDBInstanceName() );
//
// Try connecting to the database with the impersonated user token.
//
hr = GetDBSchemaVersion( g_uddiComponents.GetFullDBInstanceName(), szVerBuf, cbVerBuf );
Log( _T( "GetDBSchemaVersion returned %s, HRESULT %x." ), szVerBuf, hr );
RevertToSelf(); } else { //
// Get error from ImpersonateLoggedOnUser
//
hr = GetLastError(); } } else { Log( _T( "AddServiceAccount failed, HRESULT %x." ), hr ); }
SetCursor( hcrCurr ); } }
CloseHandle( hToken );
if( FAILED( hr ) ) { Log( _T( "Failed to verify connectivity, putting up error dialog, HRESULT %x" ), hr );
//
// not a good login, so raise error dialog and keep focus on this property page
//
DisplayUDDIErrorDialog( hDlg, IDS_LOGIN_ERROR, MB_OK | MB_ICONWARNING, hr ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 );
Log( _T( "Put up error dialog, returning." ) );
return 1; // to keep the focus on this page
} } else { Log( _T( "LogonUser failed, %x." ), GetLastError() );
//
// not a good login, so raise error dialog and keep focus on this property page
//
DisplayUDDIErrorDialog( hDlg, IDS_LOGIN_ERROR, MB_OK | MB_ICONWARNING, GetLastError() ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
//
// set the property that denotes a domain user login will be used in the iis app pool
//
g_uddiComponents.AddProperty( UDDI_WEB, TEXT( "APPPOOL_IDENTITY_TYPE" ), MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER );
//
// the web and installer needs the user name
//
g_uddiComponents.AddProperty( UDDI_WEB, TEXT( "WAM_USER_NAME" ), szDomainUser ); g_uddiComponents.AddProperty( UDDI_WEB, TEXT("WAM_PWD"), g_szPwd );
//
// the web installer needs to put the pw into the IIS app pool settings
//
_tcscpy( szRemoteUser, szRemote ); _tcscat( szRemoteUser, TEXT( "\\" ) ); _tcscat( szRemoteUser, szUser );
if( bLocalAccount ) g_uddiComponents.AddProperty( UDDI_WEB, TEXT( "LCL_USER_NAME" ), szRemoteUser ); else g_uddiComponents.AddProperty( UDDI_WEB, TEXT( "LCL_USER_NAME" ), szDomainUser ); } //
// the user specified the Network Service account
//
else { //
// set the property that denotes "Network Service"
//
g_uddiComponents.AddProperty( UDDI_WEB, TEXT( "APPPOOL_IDENTITY_TYPE" ), MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE );
//
// the web and db installers need the user name
//
TCHAR wszNetworkServiceName[ 512 ]; DWORD cbSize = 512 * sizeof( TCHAR ); BOOL b = GetWellKnownAccountName( WinNetworkServiceSid, wszNetworkServiceName, &cbSize ); if( !b ) { Log( _T( "Call to GetNetworkServiceAccountName failed." ) ); } else { Log( _T( "Network Service account name on this machine = %s" ), wszNetworkServiceName ); } g_uddiComponents.AddProperty( UDDI_WEB, TEXT( "WAM_USER_NAME" ), wszNetworkServiceName );
//
// no need for the pw, so clear out this property
//
g_uddiComponents.DeleteProperty( UDDI_WEB, TEXT( "WAM_PWD" ) );
//
// Now also save the SID for the WAM_USER
//
TCHAR szUser[ USERNAME_LEN + 1 ]; TCHAR szDomain[ 256 ]; DWORD cbUser = sizeof szUser / sizeof szUser[0]; DWORD cbDomain = sizeof szDomain / sizeof szDomain[0];
if( !GetLocalSidString( WinNetworkServiceSid, szSidStr, cbSidStr ) ) { DisplayUDDIErrorDialog( hDlg, IDS_GETSID_ERROR, MB_OK | MB_ICONWARNING, GetLastError() ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
if( !GetRemoteAcctName( szRemote, szSidStr, szUser, &cbUser, szDomain, &cbDomain ) ) { DisplayUDDIErrorDialog( hDlg, IDS_GETREMOTEACCT_ERROR, MB_OK | MB_ICONWARNING, GetLastError() ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 1 ); return 1; // to keep the focus on this page
}
_tcscpy( szRemoteUser, szDomain ); _tcscat( szRemoteUser, TEXT( "\\" ) ); _tcscat( szRemoteUser, szUser );
g_uddiComponents.AddProperty( UDDI_WEB, TEXT( "LCL_USER_NAME" ), szRemoteUser ); }
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; }
case PSN_QUERYCANCEL: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//--------------------------------------------------------------------------
BOOL CALLBACK ConfirmPasswordDlgProc( HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch( message ) { case WM_INITDIALOG: { //
// set the limit of the length of the password
//
SendMessage( GetDlgItem( hwndDlg, IDC_CONFIRM_PW ), EM_LIMITTEXT, ( WPARAM ) PASSWORD_LEN, 0 ); } break;
case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: TCHAR szPW[ PASSWORD_LEN + 1 ]; GetDlgItemText( hwndDlg, IDC_CONFIRM_PW, szPW, sizeof( szPW ) / sizeof( TCHAR ) );
if( 0 != _tcscmp( szPW, g_szPwd ) ) { DisplayUDDIErrorDialog( hwndDlg, IDS_PW_MISMATCH ); ::SetDlgItemText( hwndDlg, IDC_CONFIRM_PW, TEXT( "" ) ); return TRUE; } // fall through...
case IDCANCEL: EndDialog( hwndDlg, wParam ); return TRUE; } }
return FALSE; }
//--------------------------------------------------------------------------
INT_PTR CALLBACK WizardSummaryDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: { tstring msg; TCHAR szMsg[ 2048 ] = { 0 }; DWORD dwLen = sizeof( szMsg ) / sizeof( TCHAR ) ; int iStrLen = LoadString( g_hInstance, IDS_WIZARD_SUMMARY_GENERAL, szMsg, dwLen ); assert( iStrLen );
msg = szMsg;
if( g_uddiComponents.IsInstalling( UDDI_DB ) ) { iStrLen = LoadString( g_hInstance, IDS_WIZARD_SUMMARY_DB, szMsg, dwLen ); assert( iStrLen ); msg += TEXT( "\n\n" ); msg += szMsg; }
if( g_uddiComponents.IsInstalling( UDDI_WEB ) ) { iStrLen = LoadString( g_hInstance, IDS_WIZARD_SUMMARY_WEB, szMsg, dwLen ); assert( iStrLen ); msg += TEXT( "\n\n" ); msg += szMsg; }
if( g_uddiComponents.IsInstalling( UDDI_ADMIN ) ) { iStrLen = LoadString( g_hInstance, IDS_WIZARD_SUMMARY_ADMIN, szMsg, dwLen ); assert( iStrLen ); msg += TEXT( "\n\n" ); msg += szMsg; }
SetWindowText( GetDlgItem( hDlg, IDC_SUMMARY ), msg.c_str() );
break; }
case WM_COMMAND: break;
case WM_NOTIFY: { switch( ( ( NMHDR * )lParam )->code ) { //
// this is called once when the page is created
//
case PSN_SETACTIVE: { g_uddiComponents.UpdateAllInstallLevel(); if( g_uddiComponents.IsAnyInstalling() ) { //PropSheet_SetWizButtons( GetParent( hDlg ), 0 );
PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } else { return SkipWizardPage( hDlg ); } }
case PSN_KILLACTIVE: case PSN_WIZBACK: case PSN_WIZFINISH: case PSN_QUERYCANCEL: case PSN_WIZNEXT: { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 0 ); return 1; } } } }
return 0; }
//--------------------------------------------------------------------------
static void ParseUserAccount( PTCHAR szDomainAndUser, UINT uDomainAndUserSize, PTCHAR szUser, UINT uUserSize, PTCHAR szDomain, UINT uDomainSize, bool &bLocalAccount ) { //
// see if the user picked a local machine account
//
TCHAR szComputerName[ MAX_COMPUTERNAME_LENGTH + 1 ]; DWORD dwCompNameLen = MAX_COMPUTERNAME_LENGTH + 1;
szComputerName[ 0 ] = 0x00; GetComputerName( szComputerName, &dwCompNameLen );
bLocalAccount = false;
//
// this string is in the format <domain>\<username>,
// so look for a whack, if found parse out the domain and user name
//
_tcsncpy( szDomain, szDomainAndUser, uDomainSize ); szDomain[ uDomainSize - 1 ] = NULL;
PTCHAR pWhack = _tcschr( szDomain, '\\' );
//
// a whack was not found, so assume it is a user on the local machine
//
if( NULL == pWhack ) { //
// return the user name and a blank domain name
//
_tcsncpy( szUser, szDomainAndUser, uUserSize ); szUser[ uUserSize - 1 ] = NULL; _tcscpy( szDomain, TEXT( "" ) );
//
// if the domain or machine was not specified, then
// assume the local machine and prepend it
//
tstring cDomainAndUser = szComputerName; cDomainAndUser.append( TEXT( "\\" ) ); cDomainAndUser.append( szUser );
_tcsncpy( szDomainAndUser, cDomainAndUser.c_str(), uDomainAndUserSize );
bLocalAccount = true;
return; }
//
// null the "whack" and step to the next character
//
*pWhack = NULL; pWhack++;
_tcsncpy( szUser, pWhack, uUserSize ); szUser[ uUserSize - 1 ] = NULL;
//
// see if the user picked a local machine account.
// if he did pick a local machine account,
// null the domain and return only the login
//
if( 0 == _tcsicmp( szDomain, szComputerName ) ) { *szDomain = NULL; bLocalAccount = true; } }
//---------------------------------------------------------------------------------------
// Shows the shell dialog that allows user to browse for a directory
// Returns FALSE if the dialog was cancelled, or TRUE and the chosen directory
// otherwise. The buffer is expected to be at least MAX_PATH character long
//
BOOL ShowBrowseDirDialog( HWND hParent, LPCTSTR szTitle, LPTSTR szOutBuf ) { BOOL bRes = FALSE; TCHAR szDispName[ MAX_PATH + 1 ];
if ( IsBadStringPtr( szOutBuf, MAX_PATH ) ) return FALSE;
HRESULT hr = ::CoInitialize( NULL ); if ( FAILED( hr ) ) return FALSE; try { BROWSEINFO binfo; LPITEMIDLIST lpItemID = NULL;
ZeroMemory ( &binfo, sizeof binfo );
SHGetFolderLocation( NULL, CSIDL_DRIVES, NULL, NULL, &lpItemID );
binfo.hwndOwner = hParent; binfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_UAHINT | BIF_DONTGOBELOWDOMAIN; binfo.lpszTitle = szTitle; binfo.pszDisplayName = szDispName; binfo.lpfn = BrowseCallbackProc; binfo.pidlRoot = lpItemID;
if ( gAllowedClusterDrives.driveCount >= 0 ) binfo.lParam = (LPARAM) &gAllowedClusterDrives; else binfo.lParam = NULL;
lpItemID = SHBrowseForFolder( &binfo ); if ( !lpItemID ) bRes = FALSE; else { bRes = SHGetPathFromIDList( lpItemID, szOutBuf ); } } catch (...) { bRes = FALSE; }
::CoUninitialize(); return bRes; }
int CALLBACK BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData ) { TCHAR szBuf[ MAX_PATH + 1 ];
if ( uMsg == BFFM_SELCHANGED ) { TCHAR szDrive[ _MAX_DRIVE + 2 ]; LPITEMIDLIST lpItemID = (LPITEMIDLIST) lParam; CLST_ALLOWED_DRIVES *lpAllowedDrives = (CLST_ALLOWED_DRIVES *) lpData; BOOL bEnableOK = FALSE;
if ( SHGetPathFromIDList( lpItemID, szBuf ) ) { bEnableOK = TRUE; try { _tsplitpath( szBuf, szDrive, NULL, NULL, NULL ); size_t iDriveLen = _tcslen( szDrive );
_tcscat( szDrive, TEXT( "\\" ) );
UINT uiDevType = GetDriveType( szDrive ); if ( uiDevType != DRIVE_FIXED ) { bEnableOK = FALSE; } else if ( lpAllowedDrives ) { if ( lpAllowedDrives->driveCount > 0 ) { szDrive[ iDriveLen ] = 0; // drop the slash
BOOL bFound = FALSE;
for ( int idx = 0; idx < lpAllowedDrives->driveCount; idx++ ) { if ( !_tcsicmp( lpAllowedDrives->drives[ idx ].c_str(), szDrive ) ) { bFound = TRUE; break; } }
bEnableOK = bFound; } else if ( lpAllowedDrives->driveCount == 0 ) { bEnableOK = FALSE; } } } catch (...) { } } SendMessage ( hwnd, BFFM_ENABLEOK, 0, bEnableOK ); }
return 0; }
//
// GetWellKnownAccountName
//
// WELL_KNOWN_SID_TYPE is a system enumeration on Win XP & later, and
// Windows Server 2003 & later. It enumerates the well known SIDs.
//
// Using the functions CreateWellKnownSid, and LookupAccountSid, we
// can retrieve the account name & domain. These functions are locale
// independent.
//
BOOL GetWellKnownAccountName( WELL_KNOWN_SID_TYPE idSidWellKnown, TCHAR *pwszName, DWORD *pcbSize ) { ENTER();
//
// Initialize our output varable.
//
memset( pwszName, 0, *pcbSize );
//
// These are used for the call to LookupAccountSid.
//
TCHAR wszUserName[ 512 ]; DWORD cbUserName = 512 * sizeof( TCHAR ); TCHAR wszDomainName[ 512 ]; DWORD cbDomainName = 512 * sizeof( TCHAR );
memset( wszUserName, 0, cbUserName ); memset( wszDomainName, 0, cbDomainName );
//
// Try to allocate a buffer for the SID.
//
DWORD cbMaxSid = SECURITY_MAX_SID_SIZE; PSID psidWellKnown = LocalAlloc( LMEM_FIXED, cbMaxSid ); if( NULL == psidWellKnown ) { Log( _T( "Call to LocalAlloc failed." ) ); return FALSE; }
//
// Create the SID.
//
BOOL b = CreateWellKnownSid( idSidWellKnown, NULL, psidWellKnown, &cbMaxSid ); if( !b ) { Log( _T( "Call to CreateWellKnownSid failed." ) ); LocalFree( psidWellKnown ); return FALSE; }
//
// Use the SID to determine the user name & domain name.
//
// For example, for idSidWellKnown = WinNetworkServiceSid,
// wszDomainName = "NT AUTHORITY"
// wszUserName = "NETWORK SERVICE"
//
SID_NAME_USE snu; b = LookupAccountSid( NULL, psidWellKnown, wszUserName, &cbUserName, wszDomainName, &cbDomainName, &snu ); LocalFree( psidWellKnown ); if( !b ) { Log( _T( "Call to LookupAccountSid failed." ) ); return FALSE; } else { Log( _T( "LookupAccountSid succeeded! domain name = %s, account name = %s" ), wszDomainName, wszUserName ); _tcsncat( pwszName, wszDomainName, *pcbSize ); _tcsncat( pwszName, _T( "\\" ), *pcbSize ); _tcsncat( pwszName, wszUserName, *pcbSize );
*pcbSize = _tcslen( pwszName ) * sizeof( TCHAR ); return TRUE; } }
BOOL GrantNetworkLogonRights( LPCTSTR pwszUser ) { //
// 1. Check our params.
//
if( NULL == pwszUser ) { Log( _T( "NULL specified as domain user to function: GrantNetworkLogonRights. Returning FALSE." ) ); return FALSE; }
TCHAR wszUser[ 1024 ]; memset( wszUser, 0, 1024 * sizeof( TCHAR ) );
//
// If the user account is a local account, it will be prefixed
// with ".\" For example: ".\Administrator".
//
// For some reason, LookupAccountName (which we rely on just below) wants
// local accounts not to be prefixed with ".\".
//
if( 0 == _tcsnicmp( _T( ".\\" ), pwszUser, 2 ) ) { _tcsncpy( wszUser, &pwszUser[ 2 ], _tcslen( pwszUser ) - 2 ); } else { _tcsncpy( wszUser, pwszUser, _tcslen( pwszUser ) ); }
Log( _T( "Account we will attempt to grant network logon rights = %s." ), wszUser );
//
// 2. Get the SID of the specified user.
//
PSID pUserSID = NULL; DWORD cbUserSID = SECURITY_MAX_SID_SIZE; TCHAR wszDomain[ 1024 ]; DWORD cbDomain = 1024 * sizeof( TCHAR ); SID_NAME_USE pUse;
pUserSID = LocalAlloc( LMEM_FIXED, cbUserSID ); if( NULL == pUserSID ) { Log( _T( "Call to LocalAlloc failed." ) ); return FALSE; } memset( pUserSID, 0, cbUserSID );
BOOL fAPISuccess = LookupAccountName( NULL, wszUser, pUserSID, &cbUserSID, wszDomain, &cbDomain, &pUse );
if( !fAPISuccess ) { Log( _T( "Call to LookupAccountName failed for user: %s." ), wszUser ); LocalFree( pUserSID ); return FALSE; } else { Log( _T( "Call to LookupAccountName succeeded for user: %s." ), wszUser ); }
//
// 3. Get a handle to Policy Object.
//
LSA_UNICODE_STRING lusMachineName; lusMachineName.Length = 0; lusMachineName.MaximumLength = 0; lusMachineName.Buffer = NULL;
LSA_OBJECT_ATTRIBUTES loaObjAttrs; memset( &loaObjAttrs, 0, sizeof( LSA_OBJECT_ATTRIBUTES ) );
ACCESS_MASK accessMask = POLICY_LOOKUP_NAMES | POLICY_CREATE_ACCOUNT;
LSA_HANDLE lhPolicy = NULL;
NTSTATUS status = LsaOpenPolicy( &lusMachineName, &loaObjAttrs, accessMask, &lhPolicy ); if( STATUS_SUCCESS != status ) { Log( _T( "Call to LsaOpenPolicy failed." ) ); LocalFree( pUserSID ); return FALSE; } else { Log( _T( "Call to LsaOpenPolicy succeeded." ) ); }
//
// 4. Check & see if the user already has the account rights they need.
//
PLSA_UNICODE_STRING plusRights = NULL; ULONG ulRightsCount = 0; BOOL fHasNetworkLogonRights = FALSE;
status = LsaEnumerateAccountRights( lhPolicy, pUserSID, &plusRights, &ulRightsCount ); if( STATUS_SUCCESS == status ) { for( ULONG i = 0; i < ulRightsCount; i++ ) { if( 0 == wcscmp( plusRights[ i ].Buffer, SE_NETWORK_LOGON_NAME ) ) { fHasNetworkLogonRights = TRUE; Log( _T( "User account: %s already has network logon rights." ), wszUser ); break; } }
LsaFreeMemory( plusRights ); } else { fHasNetworkLogonRights = FALSE; }
//
// 5. If we need to add account rights, then add them.
//
BOOL fRet = FALSE; if( !fHasNetworkLogonRights ) { WCHAR wszNetworkLogon[] = L"SeNetworkLogonRight"; int iLen = wcslen( wszNetworkLogon );
LSA_UNICODE_STRING lusNetworkLogon; lusNetworkLogon.Length = iLen * sizeof( WCHAR ); lusNetworkLogon.MaximumLength = ( iLen + 1 ) * sizeof( WCHAR ); lusNetworkLogon.Buffer = wszNetworkLogon;
status = LsaAddAccountRights( lhPolicy, pUserSID, &lusNetworkLogon, 1 ); if( STATUS_SUCCESS == status ) { Log( _T( "User account: %s now has network logon rights." ), wszUser ); fRet = TRUE; } else { Log( _T( "Attempt to grant user account: %s logon rights failed." ), wszUser ); fRet = FALSE; } } else { fRet = TRUE; }
LocalFree( pUserSID ); LsaClose( lhPolicy );
return fRet; }
|