// // Copyright 1997 - Microsoft // // NEWCLNT.CPP - Handle the "New Clients" IDD_PROP_NEW_CLIENTS property page // #include "pch.h" #include #include #include #include #include #include "newclnts.h" #include "cservice.h" DEFINE_MODULE("IMADMUI") DEFINE_THISCLASS("CNewClientsTab") #define THISCLASS CNewClientsTab #define LPTHISCLASS LPCNewClientsTab #define UNKNOWN_INVALID_TEMPLATE L"??" #include #include 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); }