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
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);
|
|
}
|