Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1576 lines
42 KiB

//
// Copyright 1997 - Microsoft
//
// NEWCLNT.CPP - Handle the "New Clients" IDD_PROP_NEW_CLIENTS property page
//
#include "pch.h"
#include <dnsapi.h>
#include <ntdsapi.h>
#include <dsgetdc.h>
#include <lm.h>
#include <wininet.h>
#include "newclnts.h"
#include "cservice.h"
DEFINE_MODULE("IMADMUI")
DEFINE_THISCLASS("CNewClientsTab")
#define THISCLASS CNewClientsTab
#define LPTHISCLASS LPCNewClientsTab
#define UNKNOWN_INVALID_TEMPLATE L"??"
#include <riname.h>
#include <riname.c>
DWORD aNewClientsHelpMap[] = {
IDC_B_BROWSE, HIDC_B_BROWSE,
IDC_E_NEWMACHINEOU, HIDC_E_NEWMACHINEOU,
IDC_R_SPECIFICLOCATION, HIDC_R_SPECIFICLOCATION,
IDC_R_SAMEASUSER, HIDC_R_SAMEASUSER,
IDC_R_DOMAINDEFAULT, HIDC_R_DOMAINDEFAULT,
IDC_G_CLIENTACCOUNTLOCATION, HIDC_G_CLIENTACCOUNTLOCATION,
IDC_E_SAMPLE, HIDC_E_SAMPLE,
IDC_CB_NAMINGPOLICY, HIDC_CB_NAMINGPOLICY,
IDC_B_ADVANCED, HIDC_B_ADVANCED,
IDC_G_NAMINGFORMAT, HIDC_G_NAMINGFORMAT,
NULL, NULL
};
DWORD aAdvancedHelpMap[] = {
IDC_E_FORMAT, HIDC_E_FORMAT,
IDC_E_SAMPLE, HIDC_E_SAMPLE,
NULL, NULL
};
//
// CreateInstance()
//
LPVOID
CNewClientsTab_CreateInstance( void )
{
TraceFunc( "CNewClientsTab_CreateInstance()\n" );
LPTHISCLASS lpcc = new THISCLASS( );
if ( !lpcc ) {
RETURN(lpcc);
}
HRESULT hr = THR( lpcc->Init( ) );
if ( FAILED(hr) )
{
delete lpcc;
RETURN(NULL);
}
RETURN(lpcc);
}
//
// Constructor
//
THISCLASS::THISCLASS( ) :
_hDlg(NULL),
_punkService(NULL),
_fAdmin(FALSE),
_fChanged(FALSE),
_iCustomId(0),
_pszCustomNamingPolicy(NULL),
_pszNewMachineOU(NULL),
_pszServerDN(NULL),
_hNotify(NULL)
{
TraceClsFunc( "CNewClientsTab()\n" );
ZeroMemory(_szSampleName,DNS_MAX_LABEL_BUFFER_LENGTH *sizeof(WCHAR));
InterlockIncrement( g_cObjects );
TraceFuncExit();
}
//
// Scratch buffer used to load strings.
//
WCHAR szSamples0[ SAMPLES_LIST_SIZE ];
WCHAR szSamples1[ SAMPLES_LIST_SIZE ];
WCHAR szSamples2[ SAMPLES_LIST_SIZE ];
//
// Init()
//
HRESULT __stdcall
THISCLASS::Init( )
{
HRESULT hr = S_OK;
TraceClsFunc( "Init()\n" );
Assert( !_pszNewMachineOU );
Assert( !_pszServerDN );
HRETURN(hr);
}
//
// Destructor
//
THISCLASS::~THISCLASS( )
{
TraceClsFunc( "~CNewClientsTab()\n" );
if ( _punkService )
_punkService->Release( );
if ( _pszServerDN )
TraceFree( _pszServerDN );
if ( _pszCustomNamingPolicy )
TraceFree( _pszCustomNamingPolicy );
// tell ADS to destroy the notify object
// NOTE: Another property page may do this before us. Ignore errors.
SendMessage( _hNotify, WM_ADSPROP_NOTIFY_EXIT, 0, 0 );
InterlockDecrement( g_cObjects );
TraceFuncExit();
};
// *************************************************************************
//
// ITab
//
// *************************************************************************
STDMETHODIMP
THISCLASS::AddPages(
LPFNADDPROPSHEETPAGE lpfnAddPage,
LPARAM lParam,
LPUNKNOWN punk )
{
TraceClsFunc( "AddPages( )\n" );
HRESULT hr = S_OK;
PROPSHEETPAGE psp;
HPROPSHEETPAGE hpage;
psp.dwSize = sizeof(psp);
psp.dwFlags = PSP_USEREFPARENT | PSP_USECALLBACK;
psp.hInstance = (HINSTANCE) g_hInstance;
psp.pszTemplate = MAKEINTRESOURCE(IDD_PROP_NEW_CLIENTS);
psp.pcRefParent = (UINT *) &g_cObjects;
psp.pfnCallback = (LPFNPSPCALLBACK) PropSheetPageProc;
psp.pfnDlgProc = PropSheetDlgProc;
psp.lParam = (LPARAM) this;
hpage = CreatePropertySheetPage( &psp );
if ( hpage )
{
if ( !lpfnAddPage( hpage, lParam ) )
{
DestroyPropertySheetPage( hpage );
hr = E_FAIL;
goto Error;
}
}
punk->AddRef( ); // matching Release in the destructor
_punkService = punk;
Error:
HRETURN(hr);
}
//
// ReplacePage()
//
STDMETHODIMP
THISCLASS::ReplacePage(
UINT uPageID,
LPFNADDPROPSHEETPAGE lpfnReplaceWith,
LPARAM lParam,
LPUNKNOWN punk )
{
TraceClsFunc( "ReplacePage( ) *** NOT_IMPLEMENTED ***\n" );
RETURN(E_NOTIMPL);
}
//
// QueryInformation( )
//
STDMETHODIMP
THISCLASS::QueryInformation(
LPWSTR pszAttribute,
LPWSTR * pszResult )
{
TraceClsFunc( "QueryInformation( )\n" );
HRETURN(E_NOTIMPL);
}
//
// AllowActivation( )
//
STDMETHODIMP
THISCLASS::AllowActivation(
BOOL * pfAllow )
{
TraceClsFunc( "AllowActivation( )\n" );
HRETURN(E_NOTIMPL);
}
// ************************************************************************
//
// Property Sheet Functions
//
// ************************************************************************
//
// GenerateSample( )
//
DWORD
GenerateSample(
LPWSTR pszPolicy,
LPWSTR pszSampleOut,
LPDWORD maxLength )
{
DWORD error;
GENNAME_VARIABLES variables;
TraceClsFunc( "GenerateSample( )\n" );
if ( !pszPolicy )
HRETURN(E_POINTER);
variables.UserName = L"JOHNSMI";
variables.FirstName = L"John";
variables.LastName = L"Smith";
variables.MacAddress = L"123456789012";
variables.Counter = 123456789;
variables.AllowCounterTruncation = TRUE;
error = GenerateNameFromTemplate(
pszPolicy,
&variables,
pszSampleOut,
DNS_MAX_LABEL_BUFFER_LENGTH,
NULL,
NULL,
maxLength
);
if ( error == GENNAME_TEMPLATE_INVALID ) {
wcscpy( pszSampleOut, UNKNOWN_INVALID_TEMPLATE );
}
RETURN(error);
}
//
// _UpdateSheet()
//
HRESULT
THISCLASS::_UpdateSheet( LPWSTR pszNamingPolicy )
{
TraceClsFunc( "_UpdateSheet( )\n" );
HRESULT hr = S_FALSE;
LPWSTR pszNext;
DWORD dw;
HWND hwndCB = GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY );
if (hwndCB == NULL) {
RRETURN(GetLastError());
}
if ( pszNamingPolicy )
{
BOOL fMatched = FALSE;
INT iCount;
INT iOldCount = ComboBox_GetCurSel( hwndCB );
// Retrieve the combobox strings
dw = LoadString( g_hInstance, IDS_SAMPLENAMINGPOLICY, szSamples0, ARRAYSIZE( szSamples0 ) );
Assert( dw );
if (!dw) {
HRETURN(HRESULT_FROM_WIN32(GetLastError()));
}
iCount = 0;
pszNext = szSamples0;
while ( *pszNext )
{
LPWSTR pszFriendlyName = pszNext;
// skip the friendly name
pszNext =StrChr( pszNext, L';' );
if ( !pszNext )
break;
*pszNext = L'\0'; // terminate
pszNext++;
LPWSTR pszCodedString = pszNext;
pszNext = StrChr( pszNext, L';' );
if ( !pszNext )
break;
*pszNext = L'\0'; // teminate
if ( pszNamingPolicy && StrCmpI( pszNamingPolicy, pszCodedString ) == 0 )
{
break;
}
iCount++;
pszNext++;
}
if ( iOldCount != iCount )
{
ComboBox_SetCurSel( hwndCB, iCount );
hr = S_OK;
}
}
else
{
INT iCount = ComboBox_GetCurSel( hwndCB );
// Retrieve the combobox strings
dw = LoadString( g_hInstance, IDS_SAMPLENAMINGPOLICY, szSamples0, ARRAYSIZE( szSamples0 ) );
Assert( dw );
if (!dw) {
HRETURN(HRESULT_FROM_WIN32(GetLastError()));
}
pszNext = szSamples0;
while ( *pszNext && iCount >= 0 )
{
LPWSTR pszFriendlyName = pszNext;
// skip the friendly name
pszNext =StrChr( pszNext, L';' );
if ( !pszNext )
break;
*pszNext = L'\0'; // terminate
pszNext++;
pszNamingPolicy = pszNext;
pszNext = StrChr( pszNext, L';' );
if ( !pszNext )
break;
*pszNext = L'\0'; // teminate
iCount--;
pszNext++;
}
}
GenerateSample( pszNamingPolicy, _szSampleName, &dw );
SetDlgItemText( _hDlg, IDC_E_SAMPLE, _szSampleName );
RETURN(hr);
}
//
// _InitDialog( )
//
HRESULT
THISCLASS::_InitDialog(
HWND hDlg,
LPARAM lParam )
{
TraceClsFunc( "_InitDialog( )\n" );
HRESULT hr;
HRESULT hResult = S_OK;
DWORD dw;
LPWSTR pszNext;
HWND hwnd;
LPWSTR pszNewMachineOU = NULL;
IIntelliMirrorSAP * pimsap = NULL;
_hDlg = hDlg;
dw = LoadString( g_hInstance, IDS_SAMPLENAMINGPOLICY, szSamples1, ARRAYSIZE( szSamples1 ) );
Assert( dw );
if (!dw) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto Error;
}
Assert( _punkService );
hr = THR( _punkService->QueryInterface( IID_IIntelliMirrorSAP, (void**) &pimsap ) );
if (FAILED( hr ))
goto Error;
hr = THR( pimsap->GetNotifyWindow( &_hNotify ) );
if (FAILED( hr ))
goto Error;
ADsPropSetHwnd( _hNotify, _hDlg );
//
// Populate Naming Policy ComboBox
//
hwnd = GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY );
ComboBox_ResetContent( hwnd );
_iCustomId = 0;
pszNext = szSamples1;
while ( *pszNext )
{
// add the friendly name to the combobox
LPWSTR pszFriendlyName = pszNext;
pszNext = StrChr( pszNext, L';' );
if ( !pszNext )
break;
*pszNext = L'\0'; // terminate
ComboBox_AddString( hwnd, pszFriendlyName );
*pszNext = L';'; // restore
// skip the formatted string
pszNext++;
pszNext = StrChr( pszNext, L';' );
if ( !pszNext )
break;
pszNext++;
_iCustomId++;
}
hr = THR( pimsap->IsAdmin( &_fAdmin ) );
Assert( SUCCEEDED(hr) || _fAdmin == FALSE );
EnableWindow( GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY ), _fAdmin );
EnableWindow( GetDlgItem( _hDlg, IDC_B_ADVANCED ), _fAdmin );
EnableWindow( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ), _fAdmin );
EnableWindow( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ), _fAdmin );
EnableWindow( GetDlgItem( _hDlg, IDD_PROP_NEW_CLIENTS ), _fAdmin );
EnableWindow( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ), _fAdmin );
hr = THR( pimsap->GetNewMachineNamingPolicy( &_pszCustomNamingPolicy ) );
if (FAILED( hr ) && hr != E_ADS_PROPERTY_NOT_FOUND && hResult == S_OK )
{
hResult = hr;
}
Assert( SUCCEEDED(hr) || !_pszCustomNamingPolicy );
_UpdateSheet( _pszCustomNamingPolicy );
hr = pimsap->GetNewMachineOU( &pszNewMachineOU );
if (FAILED( hr ) && hr != E_ADS_PROPERTY_NOT_FOUND && hResult == S_OK )
{
hResult = hr;
}
Assert( SUCCEEDED(hr) || !pszNewMachineOU );
hr = THR( pimsap->GetServerDN( &_pszServerDN ) );
if (FAILED( hr ) && hr != E_ADS_PROPERTY_NOT_FOUND && hResult == S_OK )
{
hResult = hr;
}
Assert( SUCCEEDED(hr) || !_pszServerDN );
if ( pszNewMachineOU )
{
if( StrCmp( pszNewMachineOU, _pszServerDN ) !=0 )
{
hr = _MakeOUPretty( DS_FQDN_1779_NAME, DS_CANONICAL_NAME, &pszNewMachineOU );
BOOLEAN temp = _fChanged;
_fChanged =TRUE;// Prevent early turning on of the Apply button.
SetDlgItemText( _hDlg, IDC_E_NEWMACHINEOU, pszNewMachineOU );
_fChanged = temp;
EnableWindow( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), _fAdmin );
EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), _fAdmin );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ), BST_CHECKED );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ), BST_UNCHECKED );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ), BST_UNCHECKED );
}
else
{
EnableWindow( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), FALSE );
EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), FALSE );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ), BST_UNCHECKED );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ), BST_CHECKED );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ), BST_UNCHECKED );
}
}
else
{
EnableWindow( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), FALSE );
EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), FALSE );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ), BST_UNCHECKED );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ), BST_UNCHECKED );
Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ), BST_CHECKED );
}
if ( hResult != S_OK )
{
MessageBoxFromHResult( _hDlg, IDS_ERROR_READINGCOMPUTERACCOUNT, hResult );
}
Cleanup:
if ( pszNewMachineOU )
TraceFree( pszNewMachineOU );
if ( pimsap )
pimsap->Release( );
HRETURN(hr);
Error:
MessageBoxFromHResult( _hDlg, IDS_ERROR_READINGCOMPUTERACCOUNT, hr );
goto Cleanup;
}
PCWSTR
GetDCNameForServer(
PCWSTR InputPath
)
/*++
Routine Description:
Given a server name, we retrive the name of a DC for that server's domain.
We create an LDAP path of the form LDAP://DNSNAMEOFDC/DNOFDOMAIN.
Arguments:
ServerName - name of the server to validate
Return Value:
String indicating DC name. Must be freed via TraceFree().
--*/
{
PWSTR FQDN = NULL,p,DCName = NULL,DomainDN = NULL;
HRESULT hr;
HANDLE hDC;
DOMAIN_CONTROLLER_INFO *DomainControllerInfo;
hr = DNtoFQDN( (LPWSTR)InputPath, &FQDN);
if (!SUCCEEDED(hr)) {
goto Exit;
}
hr = GetDomainDN( (LPWSTR)InputPath, &DomainDN);
if (!SUCCEEDED(hr)) {
goto Exit;
}
p = StrStrI(FQDN,L".");
if (!p) {
goto Exit;
}
p += 1;
if (ERROR_SUCCESS == DsGetDcName(
NULL,
p,
NULL,
NULL,
DS_IS_DNS_NAME | DS_RETURN_DNS_NAME,
&DomainControllerInfo
)) {
//
// want a string of form:
//
// LDAP://DNSNAMEOFDC/DNOFDOMAIN
//
DCName = TraceAllocString(
LMEM_FIXED,
sizeof(L"LDAP://") +
(wcslen(DomainControllerInfo->DomainControllerName)-2)*sizeof(WCHAR) +
sizeof(L"/") +
wcslen(DomainDN)*sizeof(WCHAR) +
1 * sizeof (WCHAR)
);
if (DCName) {
wcscpy(DCName,L"LDAP://");
//
// skip the \\ in front of the DC name
//
wcscat(DCName,&DomainControllerInfo->DomainControllerName[2]);
wcscat(DCName,L"/");
wcscat(DCName,DomainDN);
}
NetApiBufferFree(DomainControllerInfo);
}
Exit:
if (FQDN) {
TraceFree( FQDN );
}
if (DomainDN) {
TraceFree( DomainDN );
}
return(DCName);
}
//
// _OnCommand( )
//
HRESULT
THISCLASS::_OnCommand( WPARAM wParam, LPARAM lParam )
{
TraceClsFunc( "_OnCommand( " );
TraceMsg( TF_FUNC, "wParam = 0x%08x, lParam = 0x%08x )\n", wParam, lParam );
BOOL fReturn = TRUE;
BOOL fChanged = FALSE;
HWND hwndCtl = (HWND) lParam;
switch( LOWORD(wParam) )
{
case IDC_B_ADVANCED:
if ( HIWORD( wParam ) == BN_CLICKED )
{
LPWSTR pszNamingPolicy = _pszCustomNamingPolicy;
HRESULT hr = _GetCurrentNamingPolicy( &_pszCustomNamingPolicy );
if ( hr != S_FALSE )
{
TraceFree( pszNamingPolicy );
}
UINT i = (UINT) DialogBoxParam( g_hInstance,
MAKEINTRESOURCE( IDD_ADVANCEDNAMIMG),
_hDlg,
AdvancedDlgProc,
(LPARAM) this );
hr = _UpdateSheet( _pszCustomNamingPolicy );
if ( i == IDOK )
{
fChanged = TRUE;
}
}
break;
case IDC_CB_NAMINGPOLICY:
if ( HIWORD( wParam ) == CBN_SELCHANGE )
{
INT iSelection = ComboBox_GetCurSel( hwndCtl );
if ( iSelection == _iCustomId )
{
UINT i = (UINT) DialogBoxParam( g_hInstance,
MAKEINTRESOURCE( IDD_ADVANCEDNAMIMG),
_hDlg,
AdvancedDlgProc,
(LPARAM) this );
HRESULT hr = _UpdateSheet( _pszCustomNamingPolicy );
if ( i == IDOK )
{
fChanged = TRUE;
}
}
else
{
_UpdateSheet( NULL );
fChanged = TRUE;
}
}
break;
case IDC_R_SPECIFICLOCATION:
if ( HIWORD( wParam ) == BN_CLICKED )
{
HWND hwnd = GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU );
EnableWindow( hwnd, _fAdmin );
EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), _fAdmin );
if ( GetWindowTextLength( hwnd ) != 0 )
{
fChanged = TRUE;
}
}
break;
case IDC_E_NEWMACHINEOU:
if ( HIWORD( wParam ) == EN_CHANGE )
{
HWND hwnd = GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU );
if ( GetWindowTextLength( hwnd ) != 0 )
{
fChanged = TRUE;
}
}
break;
case IDC_R_SAMEASUSER:
case IDC_R_DOMAINDEFAULT:
if ( HIWORD( wParam ) == BN_CLICKED )
{
EnableWindow( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), FALSE );
EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), FALSE );
fChanged = TRUE;
}
break;
case IDC_B_BROWSE:
if ( HIWORD( wParam ) == BN_CLICKED )
{
DSBROWSEINFO info;
WCHAR szCaption[ 64 ];
WCHAR szTitle[ 64 ];
WCHAR szPath[ INTERNET_MAX_URL_LENGTH ];
DWORD dw;
szCaption[0] = L'\0';
dw = LoadString( g_hInstance, IDS_BROWSEFOROU_CAPTION, szCaption, ARRAYSIZE( szCaption ) );
Assert( dw );
szTitle[0] = L'\0';
dw = LoadString( g_hInstance, IDS_BROWSEFOROU_TITLE, szTitle, ARRAYSIZE( szTitle ) );
Assert( dw );
ZeroMemory( &info, sizeof(info) );
info.cbStruct = sizeof(info);
info.hwndOwner = _hDlg;
info.pszRoot = GetDCNameForServer(_pszServerDN);
info.pszCaption = szCaption;
info.pszTitle = szTitle;
info.pszPath = szPath;
info.cchPath = ARRAYSIZE(szPath);
info.dwFlags = DSBI_ENTIREDIRECTORY;
if ( IDOK == DsBrowseForContainer( &info ) )
{
// Skip the "LDAP://" part
HRESULT hr = E_FAIL;
LPWSTR pszOU = NULL;
if (wcslen(szPath) < 8 ||
!(pszOU = TraceStrDup( &szPath[7] ))) {
// bail out, neither condition is valid.
fChanged = FALSE;
if (info.pszRoot) {
TraceFree( (HGLOBAL)info.pszRoot );
}
RRETURN(E_FAIL);
}
if ( pszOU )
{
hr = _MakeOUPretty( DS_FQDN_1779_NAME, DS_CANONICAL_NAME, &pszOU );
if (SUCCEEDED( hr ))
{
SetWindowText( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), pszOU );
fChanged = TRUE;
}
TraceFree( pszOU );
}
if (FAILED( hr ))
{
SetWindowText( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), &szPath[7] );
fChanged = TRUE;
}
}
if (info.pszRoot) {
TraceFree( (HGLOBAL)info.pszRoot );
}
}
break;
}
if ( fChanged )
{
if ( !_fChanged )
{
_fChanged = TRUE;
SendMessage( GetParent( _hDlg ), PSM_CHANGED, (WPARAM)_hDlg, 0 );
}
}
if (fReturn) {
RRETURN( S_OK );
}
RRETURN( E_FAIL );
}
//
// _ApplyChanges( )
//
HRESULT
THISCLASS::_ApplyChanges( )
{
TraceClsFunc( "_ApplyChanges( )\n" );
if ( !_fChanged )
HRETURN(S_OK); // nop
HRESULT hr;
HRESULT hResult = S_OK;
LPWSTR pszNamingPolicy = NULL;
UINT iItem;
IIntelliMirrorSAP * pimsap = NULL;
hr = THR( _punkService->QueryInterface( IID_IIntelliMirrorSAP, (void**) &pimsap ) );
if (FAILED( hr ))
goto Error;
if ( Button_GetCheck( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ) ) == BST_CHECKED )
{
HWND hwnd = GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU );
ULONG uLen = GetWindowTextLength( hwnd ) + 1;
LPWSTR pszNewMachineOU = TraceAllocString( LMEM_FIXED, uLen );
if ( pszNewMachineOU )
{
GetWindowText( hwnd, pszNewMachineOU, uLen );
hr = _MakeOUPretty( DS_CANONICAL_NAME, DS_FQDN_1779_NAME, &pszNewMachineOU );
if (SUCCEEDED( hr ))
{
hr = THR( pimsap->SetNewMachineOU( pszNewMachineOU ) );
}
TraceFree( pszNewMachineOU );
if (FAILED(hr) && hResult == S_OK )
{
hResult = hr;
SetFocus( hwnd );
}
}
}
else if ( Button_GetCheck( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ) ) == BST_CHECKED )
{
hr = THR( pimsap->SetNewMachineOU( _pszServerDN ) );
if (FAILED(hr) && hResult == S_OK )
{
hResult = hr;
SetFocus( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ) );
}
}
else
{
hr = THR( pimsap->SetNewMachineOU( NULL ) );
if (FAILED(hr) && hResult == S_OK )
{
hResult = hr;
SetFocus( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ) );
}
}
hr = _GetCurrentNamingPolicy( &pszNamingPolicy );
if (FAILED( hr ) && hResult == S_OK )
{
hResult = hr;
}
hr = THR( pimsap->SetNewMachineNamingPolicy( pszNamingPolicy ) );
if (FAILED( hr ) && hResult == S_OK )
{
SetFocus( GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY ) );
hResult = hr;
}
hr = THR( pimsap->CommitChanges( ) );
if (FAILED( hr ))
goto Error;
if ( hResult != S_OK )
{
MessageBoxFromHResult( _hDlg, IDS_ERROR_WRITINGTOCOMPUTERACCOUNT, hResult );
hr = hResult;
}
else
{
_fChanged = FALSE;
}
Cleanup:
if ( pimsap )
pimsap->Release( );
if ( pszNamingPolicy )
TraceFree( pszNamingPolicy );
// Tell DSA that someone hit Apply
SendMessage( _hNotify, WM_ADSPROP_NOTIFY_APPLY, !!SUCCEEDED( hr ), 0 );
HRETURN(hr);
Error:
MessageBoxFromHResult( _hDlg, IDS_ERROR_WRITINGTOCOMPUTERACCOUNT, hr );
goto Cleanup;
}
//
// _OnNotify( )
//
INT
THISCLASS::_OnNotify(
WPARAM wParam,
LPARAM lParam )
{
TraceClsFunc( "_OnNotify( " );
TraceMsg( TF_FUNC, "wParam = 0x%08x, lParam = 0x%08x )\n", wParam, lParam );
LPNMHDR lpnmhdr = (LPNMHDR) lParam;
switch( lpnmhdr->code )
{
case PSN_APPLY:
{
HRESULT hr;
TraceMsg( TF_WM, TEXT("WM_NOTIFY: PSN_APPLY\n"));
hr = _ApplyChanges( );
SetWindowLongPtr( _hDlg, DWLP_MSGRESULT, ( SUCCEEDED(hr) ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE ));
RETURN(TRUE);
}
break;
default:
break;
}
RETURN(FALSE);
}
//
// PropSheetDlgProc()
//
INT_PTR CALLBACK
THISCLASS::PropSheetDlgProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam )
{
//TraceMsg( TEXT("PropSheetDlgProc(") );
//TraceMsg( TF_FUNC, TEXT(" hDlg = 0x%08x, uMsg = 0x%08x, wParam = 0x%08x, lParam = 0x%08x )\n"),
// hDlg, uMsg, wParam, lParam );
LPTHISCLASS pcc = (LPTHISCLASS) GetWindowLongPtr( hDlg, GWLP_USERDATA );
if ( uMsg == WM_INITDIALOG )
{
TraceMsg( TF_WM, TEXT("WM_INITDIALOG\n"));
LPPROPSHEETPAGE psp = (LPPROPSHEETPAGE) lParam;
SetWindowLongPtr( hDlg, GWLP_USERDATA, psp->lParam );
pcc = (LPTHISCLASS) psp->lParam;
pcc->_InitDialog( hDlg, lParam );
}
if (pcc)
{
Assert( hDlg == pcc->_hDlg );
switch ( uMsg )
{
case WM_NOTIFY:
return pcc->_OnNotify( wParam, lParam );
case WM_COMMAND:
TraceMsg( TF_WM, TEXT("WM_COMMAND\n") );
pcc->_OnCommand( wParam, lParam );
break;
case WM_HELP:// F1
{
LPHELPINFO phelp = (LPHELPINFO) lParam;
WinHelp( (HWND) phelp->hItemHandle, g_cszHelpFile, HELP_WM_HELP, (DWORD_PTR) &aNewClientsHelpMap );
}
break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND) wParam, g_cszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR) &aNewClientsHelpMap );
break;
case WM_ADSPROP_PAGE_GET_NOTIFY:
{
HWND *phwnd = (HWND *) wParam;
*phwnd = pcc->_hNotify;
}
return TRUE;
}
}
return FALSE;
}
//
// PropSheetPageProc()
//
UINT CALLBACK
THISCLASS::PropSheetPageProc(
HWND hwnd,
UINT uMsg,
LPPROPSHEETPAGE ppsp )
{
TraceClsFunc( "PropSheetPageProc( " );
TraceMsg( TF_FUNC, TEXT("hwnd = 0x%08x, uMsg = 0x%08x, ppsp= 0x%08x )\n"),
hwnd, uMsg, ppsp );
switch ( uMsg )
{
case PSPCB_CREATE:
RETURN(TRUE); // create it
break;
case PSPCB_RELEASE:
LPTHISCLASS pcc = (LPTHISCLASS) ppsp->lParam;
delete pcc;
break;
}
RETURN(FALSE);
}
// ************************************************************************
//
// Advanced Namimg Dialog Proc
//
// ************************************************************************
INT_PTR CALLBACK
AdvancedDlgProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam )
{
//TraceMsg( TEXT("AdvancedDlgProc(") );
//TraceMsg( TF_FUNC, TEXT(" hDlg = 0x%08x, uMsg = 0x%08x, wParam = 0x%08x, lParam = 0x%08x )\n"),
// hDlg, uMsg, wParam, lParam );
WCHAR szFormat[ DNS_MAX_LABEL_BUFFER_LENGTH ];
LPTHISCLASS pcc = (LPTHISCLASS) GetWindowLongPtr( hDlg, GWLP_USERDATA );
if ( uMsg == WM_INITDIALOG )
{
TraceMsg( TF_WM, TEXT("WM_INITDIALOG\n"));
pcc = (LPTHISCLASS) lParam;
SetWindowLongPtr( hDlg, GWLP_USERDATA, (LPARAM) pcc );
Assert( pcc != NULL );
HWND hwnd = GetDlgItem( hDlg, IDC_E_FORMAT );
Edit_LimitText( hwnd, ARRAYSIZE(szFormat) - 1 );
LPWSTR pszNamingPolicy = NULL;
HRESULT hr = pcc->_GetCurrentNamingPolicy( &pszNamingPolicy );
if (SUCCEEDED( hr ) && (hr != S_FALSE))
{
SetWindowText( hwnd, pszNamingPolicy );
TraceFree( pszNamingPolicy );
}
}
if (pcc)
{
switch ( uMsg )
{
case WM_COMMAND:
{
switch( LOWORD( wParam ) )
{
case IDCANCEL:
if ( HIWORD( wParam ) == BN_CLICKED )
{
EndDialog( hDlg, LOWORD( wParam ) );
return TRUE;
}
break;
case IDOK:
if ( HIWORD( wParam ) == BN_CLICKED )
{
WCHAR szSample[ DNS_MAX_LABEL_BUFFER_LENGTH ];
DWORD maxLength;
DWORD nameError;
if (!GetDlgItemText( hDlg, IDC_E_FORMAT, szFormat, ARRAYSIZE(szFormat) )) {
nameError = GENNAME_TEMPLATE_INVALID;
} else {
nameError = GenerateSample( szFormat, szSample, &maxLength );
Assert( (nameError == GENNAME_NO_ERROR) ||
(nameError == GENNAME_TEMPLATE_INVALID) ||
(nameError == GENNAME_NAME_TOO_LONG) );
}
if ( nameError == GENNAME_TEMPLATE_INVALID )
{
MessageBoxFromStrings( hDlg,
IDS_ADVANCED_NAMING_RESTRICTIONS_TITLE,
IDS_ADVANCED_NAMING_RESTRICTIONS_TEXT,
MB_OK );
break;
}
else if ( nameError == GENNAME_NAME_TOO_LONG )
{
LRESULT lResult = MessageBoxFromStrings( hDlg,
IDS_DNS_NAME_LENGTH_WARNING_TITLE,
IDS_DNS_NAME_LENGTH_WARNING_TEXT,
MB_YESNO );
if ( lResult == IDNO )
break;
}
pcc->_pszCustomNamingPolicy = (LPWSTR) TraceStrDup( szFormat );
EndDialog( hDlg, LOWORD( wParam ) );
return TRUE;
}
break;
case IDC_E_FORMAT:
if ( HIWORD( wParam ) == EN_CHANGE )
{
WCHAR szSample[ DNS_MAX_LABEL_BUFFER_LENGTH ] = { L"" };
DWORD maxLength;
DWORD nameError;
if ( !GetDlgItemText( hDlg, IDC_E_FORMAT, szFormat, ARRAYSIZE(szFormat) ) )
{
nameError = GENNAME_TEMPLATE_INVALID;
}
else
{
nameError = GenerateSample( szFormat, szSample, &maxLength );
Assert( (nameError == GENNAME_NO_ERROR) ||
(nameError == GENNAME_TEMPLATE_INVALID) ||
(nameError == GENNAME_NAME_TOO_LONG) );
}
if ( DnsValidateDnsName_W( szSample ) != NO_ERROR ) {
nameError = GENNAME_TEMPLATE_INVALID;
wcscpy( szSample, UNKNOWN_INVALID_TEMPLATE );
}
SetDlgItemText( hDlg, IDC_E_SAMPLE, szSample );
EnableWindow( GetDlgItem( hDlg, IDOK ),
(BOOL)(nameError != GENNAME_TEMPLATE_INVALID) );
}
break;
}
}
break; // WM_COMMAND
case WM_HELP:// F1
{
LPHELPINFO phelp = (LPHELPINFO) lParam;
WinHelp( (HWND) phelp->hItemHandle, g_cszHelpFile, HELP_WM_HELP, (DWORD_PTR) &aAdvancedHelpMap );
}
break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND) wParam, g_cszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR) &aAdvancedHelpMap );
break;
}
}
return FALSE;
}
HRESULT
THISCLASS::_GetCurrentNamingPolicy( LPWSTR * ppszNamingPolicy )
{
TraceClsFunc( "_GetCurrentNamingPolicy( )\n" );
if ( !ppszNamingPolicy )
HRETURN(E_POINTER);
HRESULT hr = S_OK;
INT iItem = ComboBox_GetCurSel( GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY ) );
if ( iItem == - 1 )
{
*ppszNamingPolicy = NULL;
HRETURN(S_FALSE);
}
else if ( iItem == _iCustomId && _pszCustomNamingPolicy )
{
if ( *ppszNamingPolicy == _pszCustomNamingPolicy )
HRETURN(S_FALSE);
*ppszNamingPolicy = TraceStrDup( _pszCustomNamingPolicy );
if (!*ppszNamingPolicy) {
HRETURN(E_OUTOFMEMORY);
}
}
else if ( iItem != _iCustomId )
{
LPWSTR pszFormat = NULL;
LPWSTR pszNext = szSamples2;
DWORD dw;
dw = LoadString( g_hInstance, IDS_SAMPLENAMINGPOLICY, szSamples2, ARRAYSIZE( szSamples2 ) );
Assert( dw );
if (!dw) {
HRETURN(E_OUTOFMEMORY);
}
for( ; *pszNext && iItem >= 0; iItem-- )
{
// find the end of the friendly name which is terminated by a ';'
pszNext = StrChr( pszNext, L';' );
if ( !pszNext )
{
pszFormat = NULL;
break;
}
pszNext++;
pszFormat = pszNext;
// skip the internal string
pszNext = StrChr( pszNext, L';' );
if ( !pszNext )
{
pszFormat = NULL;
break;
}
// next string please...
pszNext++;
}
Assert( pszFormat );
pszNext = StrChr( pszFormat, L';' );
Assert( pszNext );
*pszNext = L'\0';
*ppszNamingPolicy = TraceStrDup( pszFormat );
}
if ( !*ppszNamingPolicy )
{
hr = E_OUTOFMEMORY;
}
HRETURN(hr);
}
typedef enum {
MOUP_SYNTACTICAL,
MOUP_LOCAL_DC,
MOUP_OTHER_DC,
MOUP_GC
} CRACK_TYPE;
HRESULT
THISCLASS::_MakeOUPretty(
DS_NAME_FORMAT inFlag,
DS_NAME_FORMAT outFlag,
LPWSTR *ppszOU )
{
TraceClsFunc("_MakeOUPretty()\n");
Assert( ppszOU );
HRESULT hr;
PDS_NAME_RESULT pResults;
DWORD dw;
HANDLE hDS;
CRACK_TYPE crackType;
//
// We might need to call DsCrackNames up to four times. The logic goes like this:
//
// Call DsCrackNames to attempt a local-only syntactical mapping.
// If that fails with DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING,
// Try the local DC.
// If can't find the local DC,
// Try the GC.
// Else if local DC failed with DS_NAME_ERROR_DOMAIN_ONLY,
// Try the DC pointed to by the local DC.
// If can't find the other DC,
// Try the GC.
//
crackType = MOUP_SYNTACTICAL;
hDS = NULL;
pResults = NULL;
while ( TRUE ) {
//
// If we have a bind handle left over from the previous pass, unbind it now.
//
if ( hDS != NULL ) {
DsUnBind( &hDS );
hDS = NULL;
}
//
// Bind to the DC or GC.
//
if ( crackType == MOUP_SYNTACTICAL ) {
hDS = NULL;
} else if ( crackType == MOUP_LOCAL_DC ) {
//
// Find a local DC.
//
PDOMAIN_CONTROLLER_INFOW pDCInfo = NULL;
dw = DsGetDcName(
NULL,
NULL,
NULL,
NULL,
DS_DIRECTORY_SERVICE_REQUIRED | DS_IP_REQUIRED,
&pDCInfo
);
if ( dw != NO_ERROR ) {
//
// Couldn't find a DC. Try the GC.
//
crackType = MOUP_GC;
continue;
}
Assert( pDCInfo != NULL );
dw = DsBind( pDCInfo->DomainControllerName, NULL, &hDS );
NetApiBufferFree( pDCInfo );
if ( dw != NO_ERROR ) {
//
// Couldn't bind to the DC. Try the GC.
//
crackType = MOUP_GC;
continue;
}
} else if ( crackType == MOUP_OTHER_DC ) {
//
// We need to talk to the DC that the local DC referred us to.
//
dw = DsBind( NULL, pResults->rItems[0].pDomain, &hDS );
if ( dw != NO_ERROR ) {
//
// Couldn't bind to the DC. Try the GC.
//
crackType = MOUP_GC;
continue;
}
} else {
//
// Bind to the GC.
//
dw = DsBind( NULL, NULL, &hDS );
if ( dw != NO_ERROR ) {
//
// Couldn't bind to the GC. Give up.
//
hr = HRESULT_FROM_WIN32( dw );
break;
}
}
//
// If we have pResults left over from a previous call, free it now.
//
if ( pResults != NULL ) {
DsFreeNameResult( pResults );
pResults = NULL;
}
//
// Try to crack the name.
//
dw = DsCrackNames( hDS,
(crackType == MOUP_SYNTACTICAL) ?
DS_NAME_FLAG_SYNTACTICAL_ONLY : DS_NAME_NO_FLAGS,
inFlag,
outFlag,
1,
ppszOU,
&pResults );
if ( dw != NO_ERROR ) {
if ( crackType == MOUP_SYNTACTICAL ) {
//
// We were doing a syntactical check. We don't expect this to fail.
//
hr = HRESULT_FROM_WIN32( dw );
break;
} else if ( crackType == MOUP_LOCAL_DC ) {
//
// We had trouble getting to the local DC. Try the GC.
//
crackType = MOUP_GC;
continue;
} else if ( crackType == MOUP_OTHER_DC ) {
//
// We had trouble getting to the other DC. Try the GC.
//
crackType = MOUP_GC;
continue;
} else {
//
// We had trouble getting to the GC. Give up.
//
hr = HRESULT_FROM_WIN32( dw );
break;
}
} else {
Assert( pResults != NULL );
Assert( pResults->cItems == 1 );
if ( pResults->rItems[0].status == DS_NAME_NO_ERROR ) {
//
// We've got what we wanted.
//
hr = S_OK;
break;
}
if ( crackType == MOUP_SYNTACTICAL ) {
if ( pResults->rItems[0].status != DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING ) {
//
// Unexpected error. Give up.
//
hr = HRESULT_FROM_WIN32( ERROR_DS_GENERIC_ERROR );
break;
}
//
// Try the local DC next.
//
crackType = MOUP_LOCAL_DC;
continue;
} else if ( crackType == MOUP_LOCAL_DC ) {
if ( pResults->rItems[0].status != DS_NAME_ERROR_DOMAIN_ONLY ) {
//
// Unexpected error. Give up.
//
hr = HRESULT_FROM_WIN32( ERROR_DS_GENERIC_ERROR );
break;
}
//
// Try the other DC next.
//
crackType = MOUP_OTHER_DC;
continue;
} else if ( crackType == MOUP_OTHER_DC ) {
//
// Unexpected error. Give up.
//
hr = HRESULT_FROM_WIN32( ERROR_DS_GENERIC_ERROR );
break;
} else {
//
// Couldn't get what we need from the GC. Give up.
//
hr = HRESULT_FROM_WIN32( ERROR_DS_GENERIC_ERROR );
break;
}
}
}
if ( hr == S_OK ) {
Assert( pResults != NULL );
Assert( pResults->cItems == 1 );
Assert( pResults->rItems[0].status == DS_NAME_NO_ERROR );
Assert( pResults->rItems[0].pName );
LPWSTR psz = TraceStrDup( pResults->rItems[0].pName );
if ( psz != NULL ) {
if (*ppszOU) {
TraceFree( *ppszOU );
*ppszOU = NULL;
}
*ppszOU = psz;
} else {
hr = E_OUTOFMEMORY;
}
}
if ( hDS != NULL ) {
DsUnBind( &hDS );
}
if ( pResults != NULL ) {
DsFreeNameResult( pResults );
}
HRETURN(hr);
}