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.

679 lines
17 KiB

  1. //
  2. // Copyright 1997 - Microsoft
  3. //
  4. // HostDlg.CPP - Handles the IDD_HOST_SERVER_PAGE
  5. //
  6. #include "pch.h"
  7. #include "dns.h"
  8. #include "hostdlg.h"
  9. #include "utils.h"
  10. #include "newcmptr.h"
  11. #include "winsock2.h"
  12. DEFINE_MODULE("IMADMUI")
  13. DEFINE_THISCLASS("CHostServerPage")
  14. #define THISCLASS CHostServerPage
  15. #define LPTHISCLASS LPCHostServerPage
  16. DWORD aHostHelpMap[] = {
  17. IDC_B_ANYSERVER, HIDC_B_ANYSERVER,
  18. IDC_B_SPECIFICSERVER, HIDC_B_SPECIFICSERVER,
  19. IDC_E_SERVER, HIDC_E_SERVER,
  20. IDC_B_BROWSE, HIDC_B_BROWSE,
  21. NULL, NULL
  22. };
  23. //
  24. // CreateInstance()
  25. //
  26. LPVOID
  27. CHostServerPage_CreateInstance( void )
  28. {
  29. TraceFunc( "CHostServerPage_CreateInstance()\n" );
  30. LPTHISCLASS lpcc = new THISCLASS( );
  31. HRESULT hr = THR( lpcc->Init( ) );
  32. if ( FAILED(hr) ) {
  33. delete lpcc;
  34. RETURN(NULL);
  35. }
  36. RETURN((LPVOID) lpcc);
  37. }
  38. //
  39. // Constructor
  40. //
  41. THISCLASS::THISCLASS( ) :
  42. _hDlg(NULL),
  43. _pNewComputerExtension(NULL),
  44. _pfActivatable(NULL)
  45. {
  46. TraceClsFunc( "CHostServerPage()\n" );
  47. InterlockIncrement( g_cObjects );
  48. TraceFuncExit();
  49. }
  50. //
  51. // Init()
  52. //
  53. STDMETHODIMP
  54. THISCLASS::Init( )
  55. {
  56. HRESULT hr = S_OK;
  57. TraceClsFunc( "Init()\n" );
  58. Assert( !_pNewComputerExtension );
  59. HRETURN(hr);
  60. }
  61. //
  62. // Destructor
  63. //
  64. THISCLASS::~THISCLASS( )
  65. {
  66. TraceClsFunc( "~CHostServerPage()\n" );
  67. InterlockDecrement( g_cObjects );
  68. TraceFuncExit();
  69. };
  70. // *************************************************************************
  71. //
  72. // ITab
  73. //
  74. // *************************************************************************
  75. STDMETHODIMP
  76. THISCLASS::AddPages(
  77. LPFNADDPROPSHEETPAGE lpfnAddPage,
  78. LPARAM lParam,
  79. LPUNKNOWN punk )
  80. {
  81. TraceClsFunc( "AddPages( )\n" );
  82. HRESULT hr = S_OK;
  83. PROPSHEETPAGE psp;
  84. HPROPSHEETPAGE hpage;
  85. Assert( lpfnAddPage );
  86. if ( !lpfnAddPage )
  87. HRETURN(E_INVALIDARG);
  88. psp.dwSize = sizeof(psp);
  89. psp.dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
  90. psp.hInstance = (HINSTANCE) g_hInstance;
  91. psp.pszTemplate = MAKEINTRESOURCE(IDD_HOST_SERVER_PAGE);
  92. psp.pcRefParent = (UINT *) &g_cObjects;
  93. psp.pfnCallback = (LPFNPSPCALLBACK) PropSheetPageProc;
  94. psp.pfnDlgProc = PropSheetDlgProc;
  95. psp.lParam = (LPARAM) this;
  96. hpage = CreatePropertySheetPage( &psp );
  97. if ( hpage ) {
  98. if ( !lpfnAddPage( hpage, lParam ) ) {
  99. DestroyPropertySheetPage( hpage );
  100. hr = THR(E_FAIL);
  101. goto Error;
  102. }
  103. }
  104. Error:
  105. HRETURN(hr);
  106. }
  107. //
  108. // ReplacePage()
  109. //
  110. STDMETHODIMP
  111. THISCLASS::ReplacePage(
  112. UINT uPageID,
  113. LPFNADDPROPSHEETPAGE lpfnReplaceWith,
  114. LPARAM lParam,
  115. LPUNKNOWN punk )
  116. {
  117. TraceClsFunc( "ReplacePage( ) *** NOT_IMPLEMENTED ***\n" );
  118. RETURN(E_NOTIMPL);
  119. }
  120. //
  121. // QueryInformation( )
  122. //
  123. STDMETHODIMP
  124. THISCLASS::QueryInformation(
  125. LPWSTR pszAttribute,
  126. LPWSTR * pszResult )
  127. {
  128. TraceClsFunc( "QueryInformation( )\n" );
  129. if ( !pszResult )
  130. HRETURN(E_POINTER);
  131. if ( !pszAttribute )
  132. HRETURN(E_INVALIDARG);
  133. HRESULT hr = E_INVALIDARG;
  134. *pszResult = NULL;
  135. if ( _wcsicmp( pszAttribute, NETBOOTSERVER ) == 0 ) {
  136. LRESULT lResult = Button_GetCheck( GetDlgItem( _hDlg, IDC_B_ANYSERVER ) );
  137. if ( lResult ) {
  138. Assert( *pszResult == NULL );
  139. hr = S_OK;
  140. }
  141. lResult = Button_GetCheck( GetDlgItem( _hDlg, IDC_B_SPECIFICSERVER ) );
  142. if ( lResult ) {
  143. HWND hwnd = GetDlgItem( _hDlg, IDC_E_SERVER );
  144. DWORD dw = Edit_GetTextLength( hwnd ) + 1;
  145. Assert( *pszResult == NULL );
  146. *pszResult = (LPWSTR) TraceAllocString( LMEM_FIXED, dw );
  147. if ( !*pszResult ) {
  148. hr = E_OUTOFMEMORY;
  149. goto Cleanup;
  150. }
  151. Edit_GetText( hwnd, *pszResult, dw );
  152. hr = S_OK;
  153. }
  154. }
  155. if ( _wcsicmp( pszAttribute, L"Server" ) == 0 ) {
  156. LRESULT lResult = Button_GetCheck( GetDlgItem( _hDlg, IDC_B_ANYSERVER ) );
  157. if ( lResult ) {
  158. WCHAR szAny[80];
  159. if (!LoadString( g_hInstance, IDS_ANY_SERVER, szAny, ARRAYSIZE(szAny)) ||
  160. !(*pszResult = (LPWSTR) TraceStrDup( szAny ))) {
  161. hr = E_OUTOFMEMORY;
  162. goto Cleanup;
  163. }
  164. hr = S_OK;
  165. }
  166. lResult = Button_GetCheck( GetDlgItem( _hDlg, IDC_B_SPECIFICSERVER ) );
  167. if ( lResult ) {
  168. HWND hwnd = GetDlgItem( _hDlg, IDC_E_SERVER );
  169. DWORD dw = Edit_GetTextLength( hwnd ) + 1;
  170. Assert( *pszResult == NULL );
  171. *pszResult = (LPWSTR) TraceAllocString( LMEM_FIXED, dw );
  172. if ( !*pszResult ) {
  173. hr = E_OUTOFMEMORY;
  174. goto Cleanup;
  175. }
  176. Edit_GetText( hwnd, *pszResult, dw );
  177. hr = S_OK;
  178. }
  179. }
  180. Cleanup:
  181. HRETURN(hr);
  182. }
  183. //
  184. // AllowActivation( )
  185. //
  186. STDMETHODIMP
  187. THISCLASS::AllowActivation(
  188. BOOL * pfAllow )
  189. {
  190. TraceClsFunc( "AllowActivation( )\n" );
  191. _pfActivatable = pfAllow;
  192. HRETURN(S_OK);
  193. }
  194. // ************************************************************************
  195. //
  196. // Property Sheet Functions
  197. //
  198. // ************************************************************************
  199. //
  200. // PropSheetDlgProc()
  201. //
  202. INT_PTR CALLBACK
  203. THISCLASS::PropSheetDlgProc(
  204. HWND hDlg,
  205. UINT uMsg,
  206. WPARAM wParam,
  207. LPARAM lParam )
  208. {
  209. //TraceMsg( TEXT("PropSheetDlgProc(") );
  210. //TraceMsg( TF_FUNC, TEXT(" hDlg = 0x%08x, uMsg = 0x%08x, wParam = 0x%08x, lParam = 0x%08x )\n"),
  211. // hDlg, uMsg, wParam, lParam );
  212. LPTHISCLASS pcc = (LPTHISCLASS) GetWindowLongPtr( hDlg, GWLP_USERDATA );
  213. if ( uMsg == WM_INITDIALOG ) {
  214. TraceMsg( TF_WM, TEXT("WM_INITDIALOG\n"));
  215. LPPROPSHEETPAGE psp = (LPPROPSHEETPAGE) lParam;
  216. SetWindowLongPtr( hDlg, GWLP_USERDATA, psp->lParam );
  217. pcc = (LPTHISCLASS) psp->lParam;
  218. pcc->_InitDialog( hDlg, lParam );
  219. }
  220. if (pcc) {
  221. Assert( hDlg == pcc->_hDlg );
  222. switch ( uMsg ) {
  223. case WM_NOTIFY:
  224. TraceMsg( TF_WM, TEXT("WM_NOTIFY\n") );
  225. return pcc->_OnNotify( wParam, lParam );
  226. case WM_COMMAND:
  227. TraceMsg( TF_WM, TEXT("WM_COMMAND\n") );
  228. return pcc->_OnCommand( wParam, lParam );
  229. case WM_HELP:// F1
  230. {
  231. LPHELPINFO phelp = (LPHELPINFO) lParam;
  232. WinHelp( (HWND) phelp->hItemHandle, g_cszHelpFile, HELP_WM_HELP, (DWORD_PTR) &aHostHelpMap );
  233. }
  234. break;
  235. case WM_CONTEXTMENU: // right mouse click
  236. WinHelp((HWND) wParam, g_cszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR) &aHostHelpMap );
  237. break;
  238. }
  239. }
  240. return FALSE;
  241. }
  242. //
  243. // PropSheetPageProc()
  244. //
  245. UINT CALLBACK
  246. THISCLASS::PropSheetPageProc(
  247. HWND hwnd,
  248. UINT uMsg,
  249. LPPROPSHEETPAGE ppsp )
  250. {
  251. TraceClsFunc( "PropSheetPageProc( " );
  252. TraceMsg( TF_FUNC, TEXT("hwnd = 0x%08x, uMsg = 0x%08x, ppsp= 0x%08x )\n"),
  253. hwnd, uMsg, ppsp );
  254. Assert( ppsp );
  255. LPTHISCLASS pcc = (LPTHISCLASS) ppsp->lParam;
  256. switch ( uMsg ) {
  257. case PSPCB_CREATE:
  258. TraceMsg( TF_WM, "PSPCB_CREATE\n" );
  259. if ( S_OK == pcc->_OnPSPCB_Create( ) ) {
  260. RETURN(TRUE); // create it
  261. }
  262. break;
  263. case PSPCB_RELEASE:
  264. TraceMsg( TF_WM, "PSPCB_RELEASE\n" );
  265. delete pcc;
  266. break;
  267. }
  268. RETURN(FALSE);
  269. }
  270. //
  271. // _OnPSPCB_Create( )
  272. //
  273. HRESULT
  274. THISCLASS::_OnPSPCB_Create( )
  275. {
  276. TraceClsFunc( "_OnPSPCB_Create( )\n" );
  277. return S_OK;
  278. }
  279. //
  280. // _InitDialog( )
  281. //
  282. HRESULT
  283. THISCLASS::_InitDialog(
  284. HWND hDlg,
  285. LPARAM lParam )
  286. {
  287. TraceClsFunc( "_InitDialog( )\n" );
  288. _hDlg = hDlg;
  289. Assert( _pNewComputerExtension );
  290. SetWindowText( GetParent( _hDlg ), _pNewComputerExtension->_pszWizTitle );
  291. SetDlgItemText( _hDlg, IDC_S_CREATEIN, _pNewComputerExtension->_pszContDisplayName );
  292. SendMessage( GetDlgItem( _hDlg, IDC_S_ICON ), STM_SETICON, (WPARAM) _pNewComputerExtension->_hIcon, 0 );
  293. Edit_LimitText( GetDlgItem( _hDlg, IDC_E_SERVER), DNS_MAX_NAME_LENGTH );
  294. Button_SetCheck( GetDlgItem( _hDlg, IDC_B_ANYSERVER ), BST_CHECKED );
  295. HRETURN(S_OK);
  296. }
  297. //
  298. // _OnCommand( )
  299. //
  300. INT
  301. THISCLASS::_OnCommand( WPARAM wParam, LPARAM lParam )
  302. {
  303. TraceClsFunc( "_OnCommand( " );
  304. TraceMsg( TF_FUNC, "wParam = 0x%08x, lParam = 0x%08x )\n", wParam, lParam );
  305. switch ( LOWORD(wParam) ) {
  306. case IDC_B_ANYSERVER:
  307. case IDC_B_SPECIFICSERVER:
  308. if ( HIWORD(wParam) == BN_CLICKED ) {
  309. LRESULT lResult = Button_GetCheck( GetDlgItem( _hDlg, IDC_B_SPECIFICSERVER ) );
  310. EnableWindow( GetDlgItem( _hDlg, IDC_E_SERVER), (BOOL)lResult );
  311. EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE), (BOOL)lResult );
  312. _UpdateWizardButtons( );
  313. }
  314. break;
  315. case IDC_E_SERVER:
  316. if ( HIWORD(wParam) == EN_CHANGE ) {
  317. _UpdateWizardButtons( );
  318. }
  319. break;
  320. case IDC_B_SEARCH:
  321. if ( HIWORD( wParam ) == BN_CLICKED ) {
  322. HRESULT hr = _OnSearch( _hDlg );
  323. }
  324. break;
  325. }
  326. RETURN(FALSE);
  327. }
  328. //
  329. // _UpdateWizardButtons( )
  330. //
  331. HRESULT
  332. THISCLASS::_UpdateWizardButtons( )
  333. {
  334. TraceClsFunc( "_UpdateWizardButtons( )\n" );
  335. HRESULT hr = S_OK;
  336. LRESULT lResult = Button_GetCheck( GetDlgItem( _hDlg, IDC_B_SPECIFICSERVER ) );
  337. if ( lResult == BST_CHECKED ) {
  338. DWORD dw = Edit_GetTextLength( GetDlgItem( _hDlg, IDC_E_SERVER ) );
  339. if ( !dw ) {
  340. PropSheet_SetWizButtons( GetParent( _hDlg ), PSWIZB_BACK );
  341. } else {
  342. PropSheet_SetWizButtons( GetParent( _hDlg ), PSWIZB_NEXT | PSWIZB_BACK );
  343. }
  344. }
  345. lResult = Button_GetCheck( GetDlgItem( _hDlg, IDC_B_ANYSERVER ) );
  346. if ( lResult == BST_CHECKED ) {
  347. PropSheet_SetWizButtons( GetParent( _hDlg ), PSWIZB_NEXT | PSWIZB_BACK );
  348. }
  349. HRETURN(hr);
  350. }
  351. //
  352. // _OnNotify( )
  353. //
  354. INT
  355. THISCLASS::_OnNotify(
  356. WPARAM wParam,
  357. LPARAM lParam )
  358. {
  359. TraceClsFunc( "_OnNotify( " );
  360. TraceMsg( TF_FUNC, "wParam = 0x%08x, lParam = 0x%08x )\n", wParam, lParam );
  361. LPNMHDR lpnmhdr = (LPNMHDR) lParam;
  362. TraceMsg( TF_WM, "NMHDR: HWND = 0x%08x, idFrom = 0x%08x, code = 0x%08x\n",
  363. lpnmhdr->hwndFrom, lpnmhdr->idFrom, lpnmhdr->code );
  364. HRESULT hr;
  365. LRESULT lResult;
  366. switch ( lpnmhdr->code ) {
  367. case PSN_WIZNEXT:
  368. lResult = Button_GetCheck( GetDlgItem( _hDlg, IDC_B_SPECIFICSERVER ) );
  369. if ( lResult == BST_CHECKED ) {
  370. WCHAR szServerName[DNS_MAX_NAME_BUFFER_LENGTH];
  371. CWaitCursor *Wait;
  372. Wait = new CWaitCursor();
  373. if (!GetDlgItemText( _hDlg, IDC_E_SERVER, szServerName, ARRAYSIZE(szServerName) )) {
  374. hr = E_INVALIDARG;
  375. } else {
  376. hr = _IsValidRISServer( szServerName );
  377. }
  378. if (Wait) {
  379. delete Wait;
  380. Wait = NULL;
  381. }
  382. SetWindowLongPtr( _hDlg, DWLP_MSGRESULT, ( SUCCEEDED(hr) ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE ));
  383. RETURN(TRUE);
  384. }
  385. break;
  386. case PSN_SETACTIVE:
  387. TraceMsg( TF_WM, "PSN_SETACTIVE\n" );
  388. Assert( _pfActivatable );
  389. if ( !*_pfActivatable ) {
  390. SetWindowLongPtr( _hDlg, DWLP_MSGRESULT, -1 ); // don't show
  391. RETURN(TRUE);
  392. }
  393. _UpdateWizardButtons( );
  394. break;
  395. case PSN_KILLACTIVE:
  396. TraceMsg( TF_WM, "PSN_KILLACTIVE\n" );
  397. break;
  398. }
  399. RETURN(FALSE);
  400. }
  401. HRESULT
  402. THISCLASS::_IsValidRISServer(
  403. IN LPCWSTR ServerName
  404. )
  405. /*++
  406. Routine Description:
  407. Validates if the specified server name points to a valid RIS server.
  408. Arguments:
  409. ServerName - name of the server to validate
  410. Return Value:
  411. HRESULT indicating outcome.
  412. (S_OK indicates that the server is a valid RIS server).
  413. --*/
  414. {
  415. HRESULT hr = E_FAIL;
  416. int retVal;
  417. CHAR mbszServerName[ DNS_MAX_NAME_BUFFER_LENGTH +1];
  418. size_t len;
  419. PHOSTENT hent;
  420. WCHAR ServerShare[MAX_PATH];
  421. TraceClsFunc("_IsValidRISServer( )\n");
  422. Assert( wcslen(ServerName) <= DNS_MAX_NAME_BUFFER_LENGTH );
  423. //
  424. // Do a DNS Lookup of the server as a first check to ensure it's a
  425. // valid name.
  426. //
  427. len = wcstombs( mbszServerName, ServerName, ARRAYSIZE( mbszServerName ) );
  428. hent = NULL;
  429. if ( !len ) {
  430. goto e0;
  431. }
  432. hent = gethostbyname( mbszServerName );
  433. if (!hent) {
  434. goto e0;
  435. }
  436. //
  437. // OK, we know the server actually resolves to a computer name. Let's search
  438. // for \\servername\reminst share. If this succeeds, we assume the server
  439. // is a valid remote install server
  440. //
  441. if (_snwprintf(
  442. ServerShare,
  443. MAX_PATH,
  444. L"\\\\%s\\reminst\\oschooser",
  445. ServerName ) < 0 ||
  446. GetFileAttributes(ServerShare) == -1) {
  447. goto e0;
  448. }
  449. return(S_OK);
  450. e0:
  451. retVal = MessageBoxFromStrings(
  452. _hDlg,
  453. IDS_PROBLEM_FINDING_SERVER_TITLE,
  454. IDS_PROBLEM_FINDING_SERVER_CONFIRM_TEXT,
  455. MB_YESNO|MB_ICONWARNING );
  456. hr = (retVal == IDYES)?S_OK:E_ADS_BAD_PARAMETER;
  457. HRETURN(hr);
  458. }
  459. HRESULT
  460. THISCLASS::_OnSearch(
  461. HWND hDlg )
  462. {
  463. TraceClsFunc( "_OnSearch( )\n" );
  464. HRESULT hr = E_FAIL;
  465. DSQUERYINITPARAMS dqip;
  466. OPENQUERYWINDOW oqw;
  467. LPDSOBJECTNAMES pDsObjects;
  468. VARIANT var;
  469. ICommonQuery * pCommonQuery = NULL;
  470. IDataObject *pdo;
  471. VariantInit( &var );
  472. hr = THR( CoCreateInstance( CLSID_CommonQuery, NULL, CLSCTX_INPROC_SERVER, IID_ICommonQuery, (PVOID *)&pCommonQuery) );
  473. if (FAILED(hr)) {
  474. goto Error;
  475. }
  476. ZeroMemory( &dqip, sizeof(dqip) );
  477. dqip.cbStruct = sizeof(dqip);
  478. dqip.dwFlags = DSQPF_NOSAVE | DSQPF_SHOWHIDDENOBJECTS | DSQPF_ENABLEADMINFEATURES;
  479. dqip.dwFlags |= DSQPF_ENABLEADVANCEDFEATURES;
  480. ZeroMemory( &oqw, sizeof(oqw) );
  481. oqw.cbStruct = sizeof(oqw);
  482. oqw.dwFlags = OQWF_SHOWOPTIONAL | OQWF_ISSUEONOPEN
  483. | OQWF_REMOVESCOPES | OQWF_REMOVEFORMS
  484. | OQWF_DEFAULTFORM | OQWF_OKCANCEL | OQWF_SINGLESELECT;
  485. oqw.clsidHandler = CLSID_DsQuery;
  486. oqw.pHandlerParameters = &dqip;
  487. oqw.clsidDefaultForm = CLSID_RISrvQueryForm;
  488. hr = pCommonQuery->OpenQueryWindow( hDlg, &oqw, &pdo);
  489. if ( SUCCEEDED(hr) && pdo) {
  490. FORMATETC fmte = {
  491. (CLIPFORMAT)g_cfDsObjectNames,
  492. NULL,
  493. DVASPECT_CONTENT,
  494. -1,
  495. TYMED_HGLOBAL};
  496. STGMEDIUM medium = { TYMED_HGLOBAL, NULL, NULL};
  497. //
  498. // Retrieve the result from the IDataObject,
  499. // in this case CF_DSOBJECTNAMES (dsclient.h)
  500. // is needed because it describes
  501. // the objects which were selected by the user.
  502. //
  503. hr = pdo->GetData(&fmte, &medium);
  504. if ( SUCCEEDED(hr) ) {
  505. DSOBJECTNAMES *pdon = (DSOBJECTNAMES*)GlobalLock(medium.hGlobal);
  506. PWSTR p,FQDN;
  507. //
  508. // we want the name of the computer object that was selected.
  509. // crack the DSOBJECTNAMES structure to get this data,
  510. // convert it into a version that the user can view, and set the
  511. // dialog text to this data.
  512. //
  513. if ( pdon ) {
  514. Assert( pdon->cItems == 1);
  515. p = (PWSTR)((ULONG_PTR)pdon + (ULONG_PTR)pdon->aObjects[0].offsetName);
  516. if (p && (p = wcsstr(p, L"LDAP://"))) {
  517. p += 6;
  518. if ((p = wcsstr(p, L"/CN="))) {
  519. p += 1;
  520. hr = DNtoFQDN( p, &FQDN);
  521. if (SUCCEEDED(hr)) {
  522. SetDlgItemText( hDlg, IDC_E_SERVER, FQDN );
  523. TraceFree( FQDN );
  524. }
  525. }
  526. }
  527. GlobalUnlock(medium.hGlobal);
  528. }
  529. }
  530. ReleaseStgMedium(&medium);
  531. pdo->Release();
  532. }
  533. Error:
  534. if ( pCommonQuery )
  535. pCommonQuery->Release();
  536. if (FAILED(hr)) {
  537. MessageBoxFromStrings(
  538. hDlg,
  539. IDS_PROBLEM_SEARCHING_TITLE,
  540. IDS_PROBLEM_SEARCHING_TEXT,
  541. MB_ICONEXCLAMATION );
  542. }
  543. HRETURN(hr);
  544. }