// // JonN 12/6/99 created // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997-2000 // #include #include #include #include #include #include "chooser2.h" #include // NetServerGetInfo JonN 2002/04/08 585301 #include // NetApiBufferFree JonN 2002/04/08 585301 //+-------------------------------------------------------------------------- // // Function: CHOOSER2_InitObjectPickerForComputers // // Synopsis: Call IDsObjectPicker::Initialize with arguments that will // set it to allow the user to pick a single computer object. // // Arguments: [pDsObjectPicker] - object picker interface instance // // Returns: Result of calling IDsObjectPicker::Initialize. // // History: 10-14-1998 DavidMun Created // 12-08-1999 JonN Copied from CHOOSER // //--------------------------------------------------------------------------- // ISSUE-2002/03/28-JonN Combine this with identical method in chooser.cpp HRESULT CHOOSER2_InitObjectPickerForComputers( IDsObjectPicker *pDsObjectPicker) { if ( !pDsObjectPicker ) return E_POINTER; // // Prepare to initialize the object picker. // Set up the array of scope initializer structures. // static const int SCOPE_INIT_COUNT = 2; DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT]; ZeroMemory(aScopeInit, sizeof(aScopeInit)); // JonN 3/28/02 // // 127399: JonN 10/30/00 JOINED_DOMAIN should be starting scope // aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopeInit[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN; aScopeInit[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE; aScopeInit[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS; aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS; aScopeInit[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopeInit[1].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN | DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE; aScopeInit[1].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS; aScopeInit[1].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS; // // Put the scope init array into the object picker init array // DSOP_INIT_INFO initInfo; ZeroMemory(&initInfo, sizeof(initInfo)); initInfo.cbSize = sizeof(initInfo); initInfo.pwzTargetComputer = NULL; // NULL == local machine initInfo.cDsScopeInfos = SCOPE_INIT_COUNT; initInfo.aDsScopeInfos = aScopeInit; initInfo.cAttributesToFetch = 1; static PCWSTR pwszDnsHostName = L"dNSHostName"; initInfo.apwzAttributeNames = &pwszDnsHostName; // // Note object picker makes its own copy of initInfo. Also note // that Initialize may be called multiple times, last call wins. // return pDsObjectPicker->Initialize(&initInfo); } //+-------------------------------------------------------------------------- // // Function: CHOOSER2_ProcessSelectedObjects // // Synopsis: Retrieve the name of the selected item from the data object // created by the object picker // // Arguments: [pdo] - data object returned by object picker // // History: 10-14-1998 DavidMun Created // 12-08-1999 JonN Copied from CHOOSER // //--------------------------------------------------------------------------- // ISSUE-2002/03/28-JonN Combine this with identical method in chooser.cpp HRESULT CHOOSER2_ProcessSelectedObjects( IDataObject* pdo, BSTR* pbstrComputerName) { if ( !pdo ) return E_POINTER; HRESULT hr = S_OK; static UINT g_cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST); STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL, NULL }; FORMATETC formatetc = { (CLIPFORMAT)g_cfDsObjectPicker, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; bool fGotStgMedium = false; do { hr = pdo->GetData(&formatetc, &stgmedium); if ( SUCCEEDED (hr) ) { fGotStgMedium = true; PDS_SELECTION_LIST pDsSelList = (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal); if (!pDsSelList) { hr = HRESULT_FROM_WIN32 (GetLastError()); break; } if ( 1 == pDsSelList->cItems ) { PDS_SELECTION psel = &(pDsSelList->aDsSelection[0]); // ISSUE-2002/03/28-JonN check for NULL == psel VARIANT* pvarDnsName = &(psel->pvarFetchedAttributes[0]); if ( NULL == pvarDnsName || VT_BSTR != pvarDnsName->vt || NULL == pvarDnsName->bstrVal || L'\0' == (pvarDnsName->bstrVal)[0] ) { *pbstrComputerName = SysAllocString( psel->pwzName); } else { *pbstrComputerName = SysAllocString( pvarDnsName->bstrVal); // // JonN 2002/04/08 585301 // Computer management snapin only attempts to use the DnsHostName // to connect to a remote computer, even when the dns name // is not valid // // Bank of America encounters a problem because they // set RegisterDnsARecord to 1, turning off client DNS // records. The dnsHostName is therefore not a valid // binding name. The fix is to test the dnsHostName. // LPBYTE pbDummy = NULL; NET_API_STATUS err = NetServerGetInfo( pvarDnsName->bstrVal, 101, &pbDummy ); if (pbDummy) { NetApiBufferFree( pbDummy ); pbDummy = NULL; } if (NERR_Success != err) { err = NetServerGetInfo( psel->pwzName, 101, &pbDummy ); if (pbDummy) { NetApiBufferFree( pbDummy ); pbDummy = NULL; } if (NERR_Success == err) { if (NULL != *pbstrComputerName) { ::SysFreeString( *pbstrComputerName ); } *pbstrComputerName = SysAllocString( psel->pwzName); } } // end new code: JonN 2002/04/08 585301 } } else hr = E_UNEXPECTED; GlobalUnlock(stgmedium.hGlobal); } } while (0); if (fGotStgMedium) { ReleaseStgMedium(&stgmedium); } return hr; } /////////////////////////////////////////////////////////////////////////////// // Generic method for launching a single-select computer picker // // Paremeters: // hwndParent (IN) - window handle of parent window // computerName (OUT) - computer name returned // // Returns S_OK if everything succeeded, S_FALSE if user pressed "Cancel" // // History: 12-08-1999 JonN Copied from CHOOSER // ////////////////////////////////////////////////////////////////////////////// HRESULT CHOOSER2_ComputerNameFromObjectPicker ( HWND hwndParent, BSTR* pbstrTargetComputer) { // // Create an instance of the object picker. The implementation in // objsel.dll is apartment model. // CComPtr spDsObjectPicker; HRESULT hr = CoCreateInstance(CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, IID_IDsObjectPicker, (void **) &spDsObjectPicker); if ( SUCCEEDED (hr) ) { // // Initialize the object picker to choose computers // hr = CHOOSER2_InitObjectPickerForComputers(spDsObjectPicker); if ( SUCCEEDED (hr) ) { // // Now pick a computer // CComPtr spDataObject; hr = spDsObjectPicker->InvokeDialog( hwndParent, &spDataObject); if ( S_OK == hr ) { hr = CHOOSER2_ProcessSelectedObjects( spDataObject, pbstrTargetComputer); } } } return hr; } const ULONG g_aHelpIDs_CHOOSER2[]= { IDC_CHOOSER2_RADIO_LOCAL_MACHINE, IDC_CHOOSER2_RADIO_LOCAL_MACHINE, IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE, IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE, IDC_CHOOSER2_EDIT_MACHINE_NAME, IDC_CHOOSER2_EDIT_MACHINE_NAME, IDC_CHOOSER2_BUTTON_BROWSE_MACHINENAMES, IDC_CHOOSER2_BUTTON_BROWSE_MACHINENAMES, IDD_CHOOSER2, (ULONG)-1, 0, 0 }; INT_PTR CALLBACK CHOOSER2_TargetComputerDialogFunc( HWND hwndDlg, // handle to dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch (uMsg) { case WM_INITDIALOG: { Edit_LimitText( GetDlgItem(hwndDlg,IDC_CHOOSER2_EDIT_MACHINE_NAME), MAX_PATH+2); // lParam is pbstrTargetComputer BSTR* pbstrTargetComputer = (BSTR*)lParam; (void) SetWindowLongPtr( hwndDlg, DWLP_USER, (LONG_PTR)pbstrTargetComputer ); (void) SendMessage( GetDlgItem(hwndDlg,IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE), BM_SETCHECK, BST_CHECKED, 0 ); (void) SetFocus( GetDlgItem(hwndDlg,IDC_CHOOSER2_EDIT_MACHINE_NAME)); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: if (BST_CHECKED == IsDlgButtonChecked( hwndDlg, IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE )) { WCHAR achTarget[MAX_PATH+3]; // allow for whackwhack ZeroMemory( achTarget, sizeof(achTarget) ); GetDlgItemText( hwndDlg, IDC_CHOOSER2_EDIT_MACHINE_NAME, achTarget, MAX_PATH+2); BSTR* pbstrTargetComputer = (BSTR*)GetWindowLongPtr( hwndDlg, DWLP_USER ); LPCWSTR pcszTargetComputer = achTarget; while (L'\\' == *pcszTargetComputer) pcszTargetComputer++; if (L'\0' != *pcszTargetComputer) *pbstrTargetComputer = SysAllocString(pcszTargetComputer); } EndDialog( hwndDlg, 1 ); break; case IDCANCEL: EndDialog( hwndDlg, 0 ); break; case IDC_CHOOSER2_BUTTON_BROWSE_MACHINENAMES: { CComBSTR sbstrTargetComputer; HRESULT hr = CHOOSER2_ComputerNameFromObjectPicker( hwndDlg, &sbstrTargetComputer ); if ( SUCCEEDED(hr) ) { LPCWSTR pcszTargetComputer = (!sbstrTargetComputer) ? NULL : (LPCWSTR)sbstrTargetComputer; SetDlgItemText( hwndDlg, IDC_CHOOSER2_EDIT_MACHINE_NAME, pcszTargetComputer ); } } break; case IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE: case IDC_CHOOSER2_RADIO_LOCAL_MACHINE: // 671670-2002/07/25-JonN use IsDlgButtonChecked (void) EnableWindow( GetDlgItem(hwndDlg,IDC_CHOOSER2_EDIT_MACHINE_NAME), (IsDlgButtonChecked(hwndDlg, IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE)) ? TRUE : FALSE ); (void) EnableWindow( GetDlgItem(hwndDlg, IDC_CHOOSER2_BUTTON_BROWSE_MACHINENAMES), (IsDlgButtonChecked(hwndDlg, IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE)) ? TRUE : FALSE ); break; default: break; } break; case WM_HELP: if (NULL != lParam) { const LPHELPINFO pHelpInfo = (LPHELPINFO)lParam; // ISSUE-2002/03/28-JonN check pHelpInfo for NULL if (pHelpInfo->iContextType == HELPINFO_WINDOW) { const HWND hwnd = (HWND)pHelpInfo->hItemHandle; (void) WinHelp( hwnd, _T("chooser.hlp"), HELP_WM_HELP, (ULONG_PTR)g_aHelpIDs_CHOOSER2); } } break; default: break; } return FALSE; } bool CHOOSER2_PickTargetComputer( IN HINSTANCE hinstance, IN HWND hwndParent, OUT BSTR* pbstrTargetComputer ) { if (NULL == pbstrTargetComputer) return false; INT_PTR nReturn = ::DialogBoxParam( hinstance, MAKEINTRESOURCE(IDD_CHOOSER2), hwndParent, CHOOSER2_TargetComputerDialogFunc, (LPARAM)pbstrTargetComputer ); return (0 < nReturn); }