Source code of Windows XP (NT5)
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.

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