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.

6126 lines
175 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. #include"stdafx.h"
  3. #include"tsprsht.h"
  4. #include"resource.h"
  5. #include"tarray.h"
  6. #include<tscfgex.h>
  7. #include<shellapi.h>
  8. #include <shlobj.h>
  9. #include <shlobjp.h>
  10. #include "regapi.h"
  11. #include <ntsecapi.h>
  12. #ifndef NT_SUCCESS
  13. #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
  14. #endif //NT_SUCCESS
  15. #ifndef STATUS_NO_MORE_ENTRIES
  16. #define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL)
  17. #endif //STATUS_NO_MORE_ENTRIES
  18. #ifndef STATUS_SUCCESS
  19. #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
  20. #endif //STATUS_SUCCESS
  21. void InitLsaString(PLSA_UNICODE_STRING LsaString,LPWSTR String);
  22. void ErrMessage( HWND hwndOwner , INT_PTR iResourceID );
  23. void TscAccessDeniedMsg( HWND hwnd );
  24. void TscGeneralErrMsg( HWND hwnd );
  25. void xxxErrMessage( HWND , INT_PTR , INT_PTR , UINT );
  26. void ReportStatusError( HWND hwnd , DWORD dwStatus );
  27. DWORD xxxLegacyLogoffCleanup( PSECURITY_DESCRIPTOR *ppSD , PBOOL );
  28. //extern BOOL g_bEditMode = FALSE;
  29. //
  30. INT_PTR APIENTRY CustomSecurityDlgProc( HWND, UINT, WPARAM, LPARAM );
  31. extern void EnableGroup( HWND hParent , LPINT rgID , BOOL bEnable );
  32. //-----------------------------------------------------------------------------
  33. typedef enum _AcluiApiIndex
  34. {
  35. ACLUI_CREATE_PAGE = 0,
  36. ACLUI_EDIT_SECURITY
  37. };
  38. //-----------------------------------------------------------------------------
  39. typedef struct _DLL_FUNCTIONS
  40. {
  41. LPCSTR pcstrFunctionName;
  42. LPVOID lpfnFunction;
  43. HINSTANCE hInst;
  44. } DLL_FUNCTIONS;
  45. //-----------------------------------------------------------------------------
  46. // not subject to localization
  47. //-----------------------------------------------------------------------------
  48. static DLL_FUNCTIONS g_aAclFunctions[] =
  49. {
  50. "CreateSecurityPage", NULL, NULL ,
  51. NULL , NULL , NULL
  52. };
  53. //-----------------------------------------------------------------------------
  54. CPropsheet::CPropsheet( )
  55. {
  56. m_cref = 0;
  57. m_hNotify = 0;
  58. m_pResNode = NULL;
  59. m_bGotUC = FALSE;
  60. m_puc = NULL;
  61. m_bPropertiesChange = FALSE;
  62. m_hMMCWindow = NULL;
  63. }
  64. //-----------------------------------------------------------------------------
  65. int CPropsheet::AddRef( )
  66. {
  67. DBGMSG( L"Propsheet Refcount at %d\n", ( m_cref + 1 ) );
  68. return InterlockedIncrement( ( LPLONG )&m_cref );
  69. }
  70. //-----------------------------------------------------------------------------
  71. // called before the destructor
  72. //-----------------------------------------------------------------------------
  73. void CPropsheet::PreDestruct( )
  74. {
  75. ICfgComp *pCfgcomp = NULL;
  76. if( m_bPropertiesChange )
  77. {
  78. // check to see if any users are logged on
  79. LONG lCount;
  80. if( m_pResNode->GetServer( &pCfgcomp ) > 0 )
  81. {
  82. if( SUCCEEDED( pCfgcomp->QueryLoggedOnCount( m_pResNode->GetConName( ) , &lCount ) ) )
  83. {
  84. TCHAR tchTitle[ 80 ];
  85. TCHAR tchMessage[ 256 ];
  86. TCHAR tchBuffer[ 336 ];
  87. UINT nFlags = MB_OK | MB_ICONINFORMATION;
  88. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_TERMSERPROP , tchTitle , SIZE_OF_BUFFER( tchTitle ) ) );
  89. if( lCount > 0 )
  90. {
  91. // Notify user that settings will not affect connected users
  92. if( lCount == 1 )
  93. {
  94. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_PROPCHANGE_WRN , tchMessage , SIZE_OF_BUFFER( tchMessage ) ) );
  95. }
  96. else if( lCount > 1 )
  97. {
  98. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_PROPCHANGE_WRN_2, tchMessage , SIZE_OF_BUFFER( tchMessage ) ) );
  99. wsprintf( tchBuffer , tchMessage , m_pResNode->GetConName( ) );
  100. }
  101. wsprintf( tchBuffer , tchMessage , m_pResNode->GetConName( ) );
  102. if( m_hMMCWindow == NULL )
  103. {
  104. nFlags |= MB_TASKMODAL;
  105. }
  106. MessageBox( m_hMMCWindow , tchBuffer , tchTitle , MB_OK | MB_ICONINFORMATION );
  107. }
  108. }
  109. pCfgcomp->Release( );
  110. }
  111. }
  112. if( m_puc != NULL )
  113. {
  114. CoTaskMemFree( m_puc );
  115. }
  116. // FreeStrings( );
  117. g_aAclFunctions[ ACLUI_CREATE_PAGE ].lpfnFunction = NULL;
  118. for( INT x = 0; x < NUM_OF_PRSHT ; ++x )
  119. {
  120. if( m_pDlg[ x ] != NULL )
  121. {
  122. delete[] m_pDlg[x];
  123. }
  124. }
  125. m_pResNode->m_bEditMode = FALSE;
  126. }
  127. //-----------------------------------------------------------------------------
  128. int CPropsheet::Release( )
  129. {
  130. if( InterlockedDecrement( ( LPLONG )&m_cref ) == 0 )
  131. {
  132. MMCFreeNotifyHandle( m_hNotify );
  133. ODS( L"Propsheet Released\n" );
  134. PreDestruct( );
  135. delete this;
  136. return 0;
  137. }
  138. DBGMSG( L"Propsheet Refcount at %d\n", m_cref );
  139. return m_cref;
  140. }
  141. //-----------------------------------------------------------------------------
  142. HRESULT CPropsheet::InitDialogs( HWND hMMC , LPPROPERTYSHEETCALLBACK pPsc , CResultNode *pResNode , LONG_PTR lNotifyHandle )
  143. {
  144. PROPSHEETPAGE psp;
  145. if( pPsc == NULL || pResNode == NULL )
  146. {
  147. return E_INVALIDARG;
  148. }
  149. m_pResNode = pResNode;
  150. m_hNotify = lNotifyHandle;
  151. BOOL bAlloc = FALSE;
  152. m_hMMCWindow = hMMC;
  153. m_pResNode->m_bEditMode = TRUE;
  154. // init array
  155. for( int x = 0; x < NUM_OF_PRSHT; x++ )
  156. {
  157. m_pDlg[ x ] = NULL;
  158. }
  159. do
  160. {
  161. m_pDlg[ 0 ] = ( CDialogPropBase * )new CGeneral( this );
  162. if( m_pDlg[ 0 ] == NULL )
  163. {
  164. ODS( L"CGeneral object allocation failed @ CPropsheet::InitDialogs\n" );
  165. break;
  166. }
  167. m_pDlg[ 1 ] = ( CDialogPropBase * )new CLogonSetting( this );
  168. if( m_pDlg[ 1 ] == NULL )
  169. {
  170. ODS( L"CLogonSetting object allocation failed @ CPropsheet::InitDialogs\n" );
  171. break;
  172. }
  173. m_pDlg[ 2 ] = ( CDialogPropBase * )new CTimeSetting( this );
  174. if( m_pDlg[ 2 ] == NULL )
  175. {
  176. ODS( L"CTimeSetting object allocation failed @ CPropsheet::InitDialogs\n" );
  177. break;
  178. }
  179. // m_pDlg[ 3 ] = ( CDialogPropBase * )new CPerm( this );
  180. m_pDlg[ 3 ] = ( CDialogPropBase * )new CEnviro( this );
  181. if( m_pDlg[ 3 ] == NULL )
  182. {
  183. ODS( L"CEnviro object allocation failed @ CPropsheet::InitDialogs\n" );
  184. break;
  185. }
  186. m_pDlg[ 4 ] = ( CDialogPropBase * )new CRemote( this );
  187. if( m_pDlg[ 4 ] == NULL )
  188. {
  189. ODS( L"CRemote object allocation failed @ CPropsheet::InitDialogs\n" );
  190. break;
  191. }
  192. m_pDlg[ 5 ] = ( CDialogPropBase * )new CClient( this );
  193. if( m_pDlg[ 5 ] == NULL )
  194. {
  195. ODS( L"CClient object allocation failed @ CPropsheet::InitDialogs\n" );
  196. break;
  197. }
  198. m_pDlg[ 6 ] = ( CDialogPropBase * )new CTransNetwork( this );
  199. if( m_pDlg[ 6 ] == NULL )
  200. {
  201. ODS( L"CTransNetwork object allocation failed @ CPropsheet::InitDialogs\n" );
  202. break;
  203. }
  204. m_pDlg[ 7 ] = ( CDialogPropBase * )new CTransAsync( this );
  205. if( m_pDlg[ 7 ] == NULL )
  206. {
  207. ODS( L"CTransAsync object allocation failed @ CPropsheet::InitDialogs\n" );
  208. break;
  209. }
  210. bAlloc = TRUE;
  211. }while( 0 );
  212. if( !bAlloc )
  213. {
  214. // try cleaning up before leaving
  215. for( x = 0; x < NUM_OF_PRSHT ; ++x )
  216. {
  217. if( m_pDlg[ x ] != NULL )
  218. {
  219. delete[] m_pDlg[x];
  220. }
  221. }
  222. return E_OUTOFMEMORY;
  223. }
  224. for( int idx = 0; idx < 5; ++idx )
  225. {
  226. if( m_pDlg[ idx ] != NULL )
  227. {
  228. if( !m_pDlg[ idx ]->GetPropertySheetPage( psp ) )
  229. {
  230. return E_UNEXPECTED;
  231. }
  232. if( FAILED( pPsc->AddPage( CreatePropertySheetPage( &psp ) ) ) )
  233. {
  234. return E_FAIL;
  235. }
  236. }
  237. }
  238. HRESULT hr = E_FAIL;
  239. if( m_pResNode != NULL )
  240. {
  241. ICfgComp *pCfgcomp = NULL;
  242. PWS pWinsta = NULL;
  243. // don't fail here third party vendor may want to use their own page
  244. if( m_pResNode->GetServer( &pCfgcomp ) > 0 )
  245. {
  246. LONG cbSize;
  247. hr = pCfgcomp->GetWSInfo( m_pResNode->GetConName( ) , &cbSize , &pWinsta );
  248. if( SUCCEEDED( hr ) )
  249. {
  250. CDialogPropBase *pDlg = NULL;
  251. CDialogPropBase *pDlgClientSettings = m_pDlg[ 5 ]; // client settings
  252. if( pWinsta->PdClass == SdNetwork )
  253. {
  254. pDlg = m_pDlg[ 6 ];
  255. }
  256. else if( pWinsta->PdClass == SdAsync )
  257. {
  258. pDlg = m_pDlg[ 7 ];
  259. }
  260. if( pDlg != NULL )
  261. {
  262. if( !pDlgClientSettings->GetPropertySheetPage( psp ) )
  263. {
  264. ODS( L"Client settings page failed to load\n" );
  265. hr = E_UNEXPECTED;
  266. }
  267. if( SUCCEEDED( hr ) )
  268. {
  269. hr = pPsc->AddPage( CreatePropertySheetPage( &psp ) );
  270. }
  271. if( SUCCEEDED( hr ) )
  272. {
  273. if( !pDlg->GetPropertySheetPage( psp ) )
  274. {
  275. ODS( L"Transport page failed to load\n" );
  276. hr = E_UNEXPECTED;
  277. }
  278. }
  279. if( SUCCEEDED( hr ) )
  280. {
  281. hr = pPsc->AddPage( CreatePropertySheetPage( &psp ) );
  282. }
  283. }
  284. CoTaskMemFree( pWinsta );
  285. }
  286. pCfgcomp->Release();
  287. }
  288. }
  289. if( SUCCEEDED( hr ) )
  290. {
  291. hr = pPsc->AddPage( GetSecurityPropertyPage( this ) );
  292. }
  293. return hr;
  294. }
  295. //The UC structure will contain data from a merger between the TSCC data and the machine policy data. We
  296. //don't want all that written to the TSCC data though. If there's a machine policy for a given field, we
  297. //want to replace its data with the data that currently exists in the TSCC section of the registry
  298. BOOL CPropsheet::ExcludeMachinePolicySettings(USERCONFIG& uc)
  299. {
  300. POLICY_TS_MACHINE p;
  301. RegGetMachinePolicy(&p);
  302. USERCONFIG origUC;
  303. //The default is to call GetUserConfig with a TRUE merge
  304. //parameter, so we have to do that before we can call
  305. //GetCurrentUserConfig which just returns the cached USERCONFIG structure
  306. if (!GetUserConfig(FALSE))
  307. return FALSE;
  308. if (!GetCurrentUserConfig(origUC, FALSE))
  309. return FALSE;
  310. //We have to do this so that the cached USERCONFIG structure
  311. //will again have the expected (merged) data
  312. if (!GetUserConfig(TRUE))
  313. return FALSE;
  314. //CRemote fields
  315. if (p.fPolicyShadow)
  316. {
  317. uc.fInheritShadow = origUC.fInheritShadow;
  318. uc.Shadow = origUC.Shadow;
  319. }
  320. //CEnviro fields
  321. if (p.fPolicyInitialProgram)
  322. {
  323. uc.fInheritInitialProgram = origUC.fInheritInitialProgram;
  324. wcscpy(uc.InitialProgram, origUC.InitialProgram);
  325. wcscpy(uc.WorkDirectory, origUC.WorkDirectory);
  326. }
  327. //CClient fields
  328. if (p.fPolicyColorDepth)
  329. {
  330. uc.fInheritColorDepth = origUC.fInheritColorDepth;
  331. uc.ColorDepth = origUC.ColorDepth;
  332. }
  333. if (p.fPolicyForceClientLptDef)
  334. uc.fForceClientLptDef = origUC.fForceClientLptDef;
  335. if (p.fPolicyDisableCdm)
  336. uc.fDisableCdm = origUC.fDisableCdm;
  337. if (p.fPolicyDisableCpm)
  338. uc.fDisableCpm = origUC.fDisableCpm;
  339. if (p.fPolicyDisableLPT)
  340. uc.fDisableLPT = origUC.fDisableLPT;
  341. if (p.fPolicyDisableCcm)
  342. uc.fDisableCcm = origUC.fDisableCcm;
  343. if (p.fPolicyDisableClip)
  344. uc.fDisableClip = origUC.fDisableClip;
  345. if (p.fPolicyDisableCam)
  346. uc.fDisableCam = origUC.fDisableCam;
  347. //CLogonSetting fields
  348. if (p.fPolicyPromptForPassword)
  349. uc.fPromptForPassword = origUC.fPromptForPassword;
  350. //CGeneral fields
  351. if (p.fPolicyMinEncryptionLevel)
  352. uc.MinEncryptionLevel = origUC.MinEncryptionLevel;
  353. //CTimeSetting fields
  354. if (p.fPolicyMaxSessionTime)
  355. uc.MaxConnectionTime = origUC.MaxConnectionTime;
  356. if (p.fPolicyMaxDisconnectionTime)
  357. uc.MaxDisconnectionTime = origUC.MaxDisconnectionTime;
  358. if (p.fPolicyMaxIdleTime)
  359. uc.MaxIdleTime = origUC.MaxIdleTime;
  360. if (p.fPolicyResetBroken)
  361. uc.fResetBroken = origUC.fResetBroken;
  362. if (p.fPolicyReconnectSame)
  363. uc.fReconnectSame = origUC.fReconnectSame;
  364. if (p.fPolicyMaxSessionTime || p.fPolicyMaxDisconnectionTime || p.fPolicyMaxIdleTime)
  365. uc.fInheritMaxSessionTime = origUC.fInheritMaxSessionTime;
  366. if (p.fPolicyResetBroken)
  367. uc.fInheritResetBroken = origUC.fInheritResetBroken;
  368. if (p.fPolicyReconnectSame)
  369. uc.fInheritReconnectSame = origUC.fInheritReconnectSame;
  370. return TRUE;
  371. }
  372. //-------------------------------------------------------------------------------
  373. // Use custom interface to persist uc to winstation
  374. //-------------------------------------------------------------------------------
  375. HRESULT CPropsheet::SetUserConfig( USERCONFIG& uc , PDWORD pdwStatus )
  376. {
  377. ICfgComp *pCfgcomp;
  378. *pdwStatus = ERROR_INVALID_PARAMETER;
  379. if( m_pResNode == NULL )
  380. return E_FAIL;
  381. if( m_pResNode->GetServer( &pCfgcomp ) == 0 )
  382. return E_FAIL;
  383. if (!ExcludeMachinePolicySettings(uc))
  384. return E_FAIL;
  385. HRESULT hr = pCfgcomp->SetUserConfig( m_pResNode->GetConName( ) , 0, &uc , pdwStatus );
  386. if( SUCCEEDED( hr ) )
  387. {
  388. m_bGotUC = FALSE;
  389. }
  390. pCfgcomp->Release( );
  391. return hr;
  392. }
  393. //-------------------------------------------------------------------------------
  394. // Use custom interface to obtain the winstation userconfig
  395. // store it in m_puc -- and return t | f
  396. //-------------------------------------------------------------------------------
  397. BOOL CPropsheet::GetUserConfig(BOOLEAN bPerformMerger)
  398. {
  399. ICfgComp *pCfgcomp;
  400. if( m_pResNode == NULL )
  401. {
  402. return FALSE;
  403. }
  404. if( m_pResNode->GetServer( &pCfgcomp ) == 0 )
  405. {
  406. return FALSE;
  407. }
  408. LONG lSzReqd;
  409. if( m_puc != NULL )
  410. {
  411. CoTaskMemFree( m_puc );
  412. m_puc = NULL;
  413. }
  414. HRESULT hr = pCfgcomp->GetUserConfig( m_pResNode->GetConName( ) , &lSzReqd , &m_puc, bPerformMerger );
  415. if( FAILED( hr ) )
  416. {
  417. hr = pCfgcomp->GetDefaultUserConfig( m_pResNode->GetConName( ) , &lSzReqd , &m_puc );
  418. }
  419. pCfgcomp->Release( );
  420. return ( FAILED( hr ) ? FALSE: TRUE );
  421. }
  422. //-------------------------------------------------------------------------------
  423. // Cache the uc
  424. //-------------------------------------------------------------------------------
  425. BOOL CPropsheet::GetCurrentUserConfig( USERCONFIG& uc, BOOLEAN bPerformMerger )
  426. {
  427. if( !m_bGotUC )
  428. {
  429. m_bGotUC = GetUserConfig(bPerformMerger);
  430. }
  431. if( m_puc != NULL )
  432. {
  433. uc = *m_puc;
  434. }
  435. return m_bGotUC;
  436. }
  437. //*******************************************************************************
  438. //-------------------------------------------------------------------------------
  439. // OnNotify - base class method
  440. //-------------------------------------------------------------------------------
  441. BOOL CDialogPropBase::OnNotify( int idCtrl , LPNMHDR pnmh , HWND hDlg )
  442. {
  443. UNREFERENCED_PARAMETER( idCtrl );
  444. if( pnmh->code == PSN_APPLY )
  445. {
  446. if( !m_bPersisted )
  447. {
  448. m_bPersisted = PersistSettings( hDlg );
  449. }
  450. }
  451. else if( pnmh->code == PSN_KILLACTIVE )
  452. {
  453. if( !m_bPersisted )
  454. {
  455. if( !IsValidSettings( hDlg ) )
  456. {
  457. SetWindowLongPtr( hDlg , DWLP_MSGRESULT , PSNRET_INVALID_NOCHANGEPAGE );
  458. return TRUE;
  459. }
  460. }
  461. }
  462. return FALSE;
  463. }
  464. //-------------------------------------------------------------------------------
  465. // OnCOntextMenu -- base class operation
  466. //-------------------------------------------------------------------------------
  467. BOOL CDialogPropBase::OnContextMenu( HWND hwnd , POINT& pt )
  468. {
  469. UNREFERENCED_PARAMETER( pt );
  470. TCHAR tchHelpFile[ MAX_PATH ];
  471. ODS( L"CDialogPropBase::OnContextMenu\n" );
  472. if( m_hWnd == GetParent( hwnd ) )
  473. {
  474. //
  475. // Make sure its not a dummy window
  476. //
  477. if( GetDlgCtrlID( hwnd ) <= ( int )-1 )
  478. {
  479. return FALSE;
  480. }
  481. ULONG_PTR rgdw[ 2 ];
  482. rgdw[ 0 ] = GetDlgCtrlID( hwnd );
  483. rgdw[ 1 ] = GetWindowContextHelpId( hwnd );
  484. LoadString( _Module.GetModuleInstance( ) , IDS_HELPFILE , tchHelpFile , SIZE_OF_BUFFER( tchHelpFile ) );
  485. WinHelp( hwnd , tchHelpFile , HELP_CONTEXTMENU , ( ULONG_PTR )&rgdw );
  486. }
  487. return TRUE;
  488. }
  489. //-------------------------------------------------------------------------------
  490. // Each control has a helpid assign to them. Some controls share the same topic
  491. // check for these.
  492. //-------------------------------------------------------------------------------
  493. BOOL CDialogPropBase::OnHelp( HWND hwnd , LPHELPINFO lphi )
  494. {
  495. UNREFERENCED_PARAMETER( hwnd );
  496. TCHAR tchHelpFile[ MAX_PATH ];
  497. //
  498. // For the information to winhelp api
  499. //
  500. if( IsBadReadPtr( lphi , sizeof( HELPINFO ) ) )
  501. {
  502. return FALSE;
  503. }
  504. if( (short)lphi->iCtrlId <= -1 )
  505. {
  506. return FALSE;
  507. }
  508. LoadString( _Module.GetModuleInstance( ) , IDS_HELPFILE , tchHelpFile , SIZE_OF_BUFFER( tchHelpFile ) );
  509. DWORD rgdw[ 4 ] = {0,0,0,0};
  510. rgdw[ 0 ] = ( DWORD )lphi->iCtrlId;
  511. rgdw[ 1 ] = ( DWORD )lphi->dwContextId;
  512. WinHelp( ( HWND )lphi->hItemHandle , tchHelpFile , HELP_WM_HELP , ( ULONG_PTR )&rgdw );//lphi->dwContextId );
  513. return TRUE;
  514. }
  515. //*****************************************************************************
  516. // General dialog
  517. CGeneral::CGeneral( CPropsheet *pSheet )
  518. {
  519. m_pParent = pSheet;
  520. m_pEncrypt = NULL;
  521. m_DefaultEncryptionLevelIndex = 0;
  522. m_nOldSel = ( INT_PTR )-1;
  523. }
  524. //-----------------------------------------------------------------------------
  525. BOOL CGeneral::OnInitDialog( HWND hDlg , WPARAM wp , LPARAM lp )
  526. {
  527. if( m_pParent == NULL )
  528. {
  529. ODS( L"CGeneral::OnInitDialog - PropertySheet: Parent object lost!!!\n" );
  530. return FALSE;
  531. }
  532. m_pParent->AddRef( );
  533. USERCONFIG uc;
  534. ZeroMemory( &uc , sizeof( USERCONFIG ) );
  535. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  536. {
  537. ODS( L"CGeneral::OnInitDialog - PropertySheet: GetCurrentUserConfig failed!!!\n" );
  538. return FALSE;
  539. }
  540. // Security
  541. SendMessage( GetDlgItem( hDlg , IDC_CHECK_GEN_AUTHEN ) , BM_SETCHECK , ( WPARAM )uc.fUseDefaultGina , 0 );
  542. // Network Transport
  543. if( m_pParent->m_pResNode == NULL )
  544. {
  545. return FALSE;
  546. }
  547. ICfgComp *pCfgcomp;
  548. ULONG cbSize = 0;
  549. ULONG ulItems = 0;
  550. do
  551. {
  552. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  553. {
  554. break;
  555. }
  556. // Set Connection name
  557. SetWindowText( GetDlgItem( hDlg , IDC_STATIC_CONNAME ) , m_pParent->m_pResNode->GetConName( ) );
  558. PWS pWinSta = NULL;
  559. if( SUCCEEDED( pCfgcomp->GetWSInfo( m_pParent->m_pResNode->GetConName( ) , ( PLONG )&cbSize , &pWinSta ) ) )
  560. {
  561. SendMessage( GetDlgItem( hDlg , IDC_EDIT_GEN_COMMENT ) , EM_SETLIMITTEXT , ( WPARAM )WINSTATIONCOMMENT_LENGTH , 0 );
  562. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_GEN_COMMENT ) , pWinSta->Comment );
  563. //m_pParent->m_pResNode->GetComment( ) );
  564. SetWindowText( GetDlgItem( hDlg , IDC_STATIC_GEN_TYPE ) , m_pParent->m_pResNode->GetTypeName( ) );
  565. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_GENERAL_TRANSPORT ) , pWinSta->pdName );
  566. // security
  567. // Encryption *pEncrypt;
  568. if( SUCCEEDED( pCfgcomp->GetEncryptionLevels( m_pParent->m_pResNode->GetConName( ) , WsName , &ulItems , &m_pEncrypt ) ) )
  569. {
  570. BOOL bSet = FALSE;
  571. for( ULONG i = 0; i < ulItems; ++i )
  572. {
  573. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_ENCRYPT ) , CB_ADDSTRING , 0 , ( LPARAM )m_pEncrypt[ i ].szLevel );
  574. if(m_pEncrypt[ i ].Flags & ELF_DEFAULT)
  575. {
  576. m_DefaultEncryptionLevelIndex = i;
  577. }
  578. if( uc.MinEncryptionLevel == m_pEncrypt[ i ].RegistryValue )
  579. {
  580. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_ENCRYPT ) , CB_SETCURSEL , ( WPARAM )i , 0);
  581. bSet = TRUE;
  582. }
  583. }
  584. POLICY_TS_MACHINE p;
  585. RegGetMachinePolicy(&p);
  586. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_GEN_ENCRYPT), !p.fPolicyMinEncryptionLevel);
  587. if (p.fPolicyFipsEnabled)
  588. {
  589. // FIPS is always the last item in the list so set it as selected
  590. SendMessage(GetDlgItem(hDlg, IDC_COMBO_GEN_ENCRYPT), CB_SETCURSEL, (WPARAM)ulItems - 1 , 0);
  591. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_GEN_ENCRYPT), FALSE);
  592. }
  593. if(!bSet)
  594. {
  595. uc.MinEncryptionLevel = (UCHAR)(m_pEncrypt[m_DefaultEncryptionLevelIndex].RegistryValue);
  596. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_ENCRYPT ) , CB_SETCURSEL , ( WPARAM )m_DefaultEncryptionLevelIndex, 0 );
  597. }
  598. OnCommand( CBN_SELCHANGE , IDC_COMBO_GEN_ENCRYPT , GetDlgItem( hDlg , IDC_COMBO_GEN_ENCRYPT ) );
  599. if( !IsWindowEnabled( GetDlgItem( hDlg , IDC_STATIC_GEN_DESCR ) ) )
  600. {
  601. RECT rc;
  602. RECT rc2;
  603. GetWindowRect( GetDlgItem( hDlg , IDC_STATIC_CONGRP ) , &rc );
  604. GetWindowRect( GetDlgItem( hDlg , IDC_STATIC_GEN_DESCR ) , &rc2 );
  605. rc.bottom = rc2.top;
  606. MapWindowPoints( NULL , hDlg , ( LPPOINT )&rc , 2 );
  607. SetWindowPos( GetDlgItem( hDlg , IDC_STATIC_CONGRP ) , 0 , 0 , 0 , rc.right - rc.left , rc.bottom - rc.top , SWP_NOMOVE | SWP_SHOWWINDOW );
  608. //resize window
  609. }
  610. }
  611. else
  612. {
  613. // no encryption info insert value to none and grey out the control
  614. TCHAR tchNone[ 80 ];
  615. LoadString( _Module.GetResourceInstance( ) , IDS_NONE , tchNone , SIZE_OF_BUFFER( tchNone ) );
  616. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_ENCRYPT ) , CB_ADDSTRING , 0 , ( LPARAM )tchNone );
  617. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_ENCRYPT ) , CB_SETCURSEL , 0 , 0 );
  618. EnableWindow( GetDlgItem( hDlg , IDC_COMBO_GEN_ENCRYPT ) , FALSE );
  619. EnableWindow( GetDlgItem( hDlg , IDC_STATIC_CONGRP ) , FALSE );
  620. }
  621. CoTaskMemFree( pWinSta );
  622. }
  623. // check to see if session is readonly
  624. BOOL bReadOnly;
  625. if( SUCCEEDED( pCfgcomp->IsSessionReadOnly( &bReadOnly ) ) )
  626. {
  627. if( bReadOnly )
  628. {
  629. // make edit controls read-only
  630. SendMessage( GetDlgItem( hDlg , IDC_EDIT_GEN_COMMENT ) , EM_SETREADONLY , ( WPARAM )TRUE , 0 );
  631. // disable the remaining controls
  632. INT rgIds[] = { IDC_CHECK_GEN_AUTHEN , IDC_STATIC_CONGRP, IDC_COMBO_GEN_ENCRYPT , -1 };
  633. EnableGroup( hDlg , &rgIds[ 0 ] , FALSE );
  634. }
  635. }
  636. pCfgcomp->Release( );
  637. }while( 0 );
  638. m_bPersisted = TRUE;
  639. return CDialogPropBase::OnInitDialog( hDlg , wp , lp );
  640. }
  641. //-----------------------------------------------------------------------------
  642. INT_PTR CALLBACK CGeneral::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  643. {
  644. CGeneral *pDlg;
  645. if( msg == WM_INITDIALOG )
  646. {
  647. CGeneral *pDlg = ( CGeneral * )( ( PROPSHEETPAGE *)lp )->lParam ;
  648. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  649. if( !IsBadReadPtr( pDlg , sizeof( CGeneral ) ) )
  650. {
  651. pDlg->OnInitDialog( hwnd , wp , lp );
  652. }
  653. return 0;
  654. }
  655. else
  656. {
  657. pDlg = ( CGeneral * )GetWindowLongPtr( hwnd , DWLP_USER );
  658. if( IsBadReadPtr( pDlg , sizeof( CGeneral ) ) )
  659. {
  660. return FALSE;
  661. }
  662. }
  663. switch( msg )
  664. {
  665. case WM_NCDESTROY:
  666. pDlg->OnDestroy( );
  667. break;
  668. case WM_COMMAND:
  669. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  670. break;
  671. case WM_CONTEXTMENU:
  672. {
  673. POINT pt;
  674. pt.x = LOWORD( lp );
  675. pt.y = HIWORD( lp );
  676. pDlg->OnContextMenu( ( HWND )wp , pt );
  677. }
  678. break;
  679. case WM_HELP:
  680. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  681. break;
  682. case WM_NOTIFY:
  683. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  684. }
  685. return FALSE;
  686. }
  687. //-----------------------------------------------------------------------------
  688. BOOL CGeneral::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  689. {
  690. if( wNotifyCode == BN_CLICKED || wNotifyCode == EN_CHANGE )
  691. {
  692. m_bPersisted = FALSE;
  693. }
  694. else if( wNotifyCode == CBN_SELCHANGE && wID == IDC_COMBO_GEN_ENCRYPT )
  695. {
  696. if( SendMessage( hwndCtrl , CB_GETDROPPEDSTATE , 0 , 0 ) == FALSE )
  697. {
  698. INT_PTR nSel = SendMessage( hwndCtrl , CB_GETCURSEL , 0 , 0 );
  699. if( nSel != CB_ERR )
  700. {
  701. if( nSel != m_nOldSel && m_pEncrypt != NULL )
  702. {
  703. if( m_pEncrypt[ nSel ].szDescr[ 0 ] == 0 )
  704. {
  705. EnableWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCRTITLE ) , FALSE );
  706. EnableWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCR ) , FALSE );
  707. ShowWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCRTITLE ) , SW_HIDE );
  708. ShowWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCR ) , SW_HIDE );
  709. }
  710. else
  711. {
  712. ShowWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCRTITLE ) , SW_SHOW );
  713. ShowWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCR ) , SW_SHOW );
  714. EnableWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCR ) , TRUE );
  715. EnableWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCRTITLE ) , TRUE );
  716. SetWindowText( GetDlgItem( GetParent( hwndCtrl ) , IDC_STATIC_GEN_DESCR ) , m_pEncrypt[ nSel ].szDescr );
  717. }
  718. m_bPersisted = FALSE;
  719. m_nOldSel = nSel;
  720. }
  721. }
  722. }
  723. }
  724. else if( wNotifyCode == ALN_APPLY )
  725. {
  726. SendMessage( GetParent( hwndCtrl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  727. return FALSE;
  728. }
  729. if( !m_bPersisted )
  730. {
  731. SendMessage( GetParent( GetParent( hwndCtrl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtrl ) , 0 );
  732. }
  733. return FALSE;
  734. }
  735. //-----------------------------------------------------------------------------
  736. BOOL CGeneral::GetPropertySheetPage( PROPSHEETPAGE& psp )
  737. {
  738. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  739. psp.dwSize = sizeof( PROPSHEETPAGE );
  740. psp.dwFlags = PSP_DEFAULT;
  741. psp.hInstance = _Module.GetResourceInstance( );
  742. psp.pszTemplate = MAKEINTRESOURCE( IDD_GENERAL );
  743. psp.lParam = ( LPARAM )this;
  744. psp.pfnDlgProc = CGeneral::DlgProc;
  745. return TRUE;
  746. }
  747. //-----------------------------------------------------------------------------
  748. BOOL CGeneral::PersistSettings( HWND hDlg )
  749. {
  750. HRESULT hr;
  751. if( IsValidSettings( hDlg ) )
  752. {
  753. ICfgComp *pCfgcomp;
  754. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  755. {
  756. return FALSE;
  757. }
  758. WS *pWinsta = NULL;
  759. LONG lSize = 0;
  760. hr = pCfgcomp->GetWSInfo( m_pParent->m_pResNode->GetConName( ) , &lSize , &pWinsta );
  761. if( SUCCEEDED( hr ) )
  762. {
  763. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_GEN_COMMENT ) , pWinsta->Comment , WINSTATIONCOMMENT_LENGTH + 1 );
  764. m_pParent->m_pResNode->SetComment( pWinsta->Comment , lstrlen( pWinsta->Comment ) );
  765. DWORD dwStatus;
  766. hr = pCfgcomp->UpDateWS( pWinsta , UPDATE_COMMENT , &dwStatus, FALSE );
  767. if( FAILED( hr ) )
  768. {
  769. // report error
  770. ReportStatusError( GetDlgItem( hDlg , IDC_EDIT_GEN_COMMENT ) , dwStatus );
  771. }
  772. CoTaskMemFree( pWinsta );
  773. }
  774. if( SUCCEEDED( hr ) )
  775. {
  776. USERCONFIG uc;
  777. if( m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  778. {
  779. if( m_pEncrypt != NULL )
  780. {
  781. UINT index = ( UCHAR )SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_ENCRYPT ) , CB_GETCURSEL , 0 , 0 );
  782. if(index == CB_ERR )
  783. {
  784. uc.MinEncryptionLevel =(UCHAR) m_pEncrypt[m_DefaultEncryptionLevelIndex].RegistryValue;
  785. }
  786. else
  787. {
  788. uc.MinEncryptionLevel = (UCHAR) m_pEncrypt[index].RegistryValue;
  789. }
  790. }
  791. else
  792. {
  793. uc.MinEncryptionLevel = 0;
  794. }
  795. uc.fUseDefaultGina = SendMessage( GetDlgItem( hDlg , IDC_CHECK_GEN_AUTHEN ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED;
  796. DWORD dwStatus = 0;
  797. hr = m_pParent->SetUserConfig( uc , &dwStatus );
  798. if( FAILED( hr ) )
  799. {
  800. // report error
  801. ReportStatusError( hDlg , dwStatus );
  802. }
  803. }
  804. }
  805. if( SUCCEEDED( hr ) )
  806. {
  807. ODS( L"TSCC : Forcing reg update on General Page\n" );
  808. VERIFY_S( S_OK , pCfgcomp->ForceUpdate( ) );
  809. VERIFY_S( S_OK , pCfgcomp->Refresh( ) );
  810. // global flag can only be set to true
  811. m_pParent->m_bPropertiesChange = TRUE;
  812. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  813. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  814. return TRUE;
  815. }
  816. pCfgcomp->Release( );
  817. }
  818. return FALSE;
  819. }
  820. //-----------------------------------------------------------------------------
  821. BOOL CGeneral::OnDestroy( )
  822. {
  823. if( m_pEncrypt != NULL )
  824. {
  825. CoTaskMemFree( m_pEncrypt );
  826. m_pEncrypt = NULL;
  827. }
  828. m_pParent->Release( );
  829. return CDialogPropBase::OnDestroy( );
  830. }
  831. //*****************************************************************************
  832. CTransNetwork::CTransNetwork( CPropsheet *pSheet )
  833. {
  834. ASSERT( pSheet != NULL );
  835. m_pParent = pSheet;
  836. // this now behaves as the last combx selection
  837. m_ulOldLanAdapter = ( ULONG )-1;
  838. m_oldID = ( WORD )-1;
  839. m_uMaxInstOld = ( ULONG )-1;
  840. }
  841. //-----------------------------------------------------------------------------
  842. INT_PTR CALLBACK CTransNetwork::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  843. {
  844. CTransNetwork *pDlg;
  845. if( msg == WM_INITDIALOG )
  846. {
  847. CTransNetwork *pDlg = ( CTransNetwork * )( ( PROPSHEETPAGE *)lp )->lParam ;
  848. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  849. if( !IsBadReadPtr( pDlg , sizeof( CTransNetwork ) ) )
  850. {
  851. pDlg->OnInitDialog( hwnd , wp , lp );
  852. }
  853. return 0;
  854. }
  855. else
  856. {
  857. pDlg = ( CTransNetwork * )GetWindowLongPtr( hwnd , DWLP_USER );
  858. if( IsBadReadPtr( pDlg , sizeof( CTransNetwork ) ) )
  859. {
  860. return FALSE;
  861. }
  862. }
  863. switch( msg )
  864. {
  865. case WM_NCDESTROY:
  866. pDlg->OnDestroy( );
  867. break;
  868. case WM_COMMAND:
  869. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  870. break;
  871. case WM_CONTEXTMENU:
  872. {
  873. POINT pt;
  874. pt.x = LOWORD( lp );
  875. pt.y = HIWORD( lp );
  876. pDlg->OnContextMenu( ( HWND )wp , pt );
  877. }
  878. break;
  879. case WM_HELP:
  880. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  881. break;
  882. case WM_NOTIFY:
  883. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  884. }
  885. return FALSE;
  886. }
  887. //-----------------------------------------------------------------------------
  888. BOOL CTransNetwork::OnInitDialog( HWND hDlg , WPARAM wp , LPARAM lp )
  889. {
  890. BOOL bReadOnly;
  891. HICON hIcon;
  892. m_pParent->AddRef( );
  893. SendMessage( GetDlgItem( hDlg , IDC_SPINCTR_GEN ) , UDM_SETRANGE32 , 0 , ( LPARAM )999999 );
  894. if( m_pParent->m_pResNode == NULL )
  895. {
  896. m_bPersisted = TRUE;
  897. return FALSE;
  898. }
  899. ICfgComp *pCfgcomp = NULL;
  900. ULONG cbSize = 0;
  901. ULONG ulItems = 0;
  902. PGUIDTBL pGuidtbl = NULL;
  903. do
  904. {
  905. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  906. {
  907. ODS( L"CTransNetwork::OnInitDialog - GetServer failed\n" );
  908. break;
  909. }
  910. WS *pWinSta = NULL;
  911. pCfgcomp->ForceUpdate();
  912. pCfgcomp->Refresh();
  913. if( FAILED( pCfgcomp->GetWSInfo( m_pParent->m_pResNode->GetConName( ) , ( PLONG )&cbSize , &pWinSta ) ) )
  914. {
  915. ODS( L"TSCC: GetWSInfo failed in TransNetwork::OnInitDialog\n" );
  916. break;
  917. }
  918. ISettingsComp* pISettingComp = NULL;
  919. HRESULT hr;
  920. DWORD dwStatus;
  921. DWORD nVal;
  922. hr = pCfgcomp->QueryInterface( IID_ISettingsComp, (void **) &pISettingComp );
  923. //
  924. // Assume we are not remote admin if anything go wrong
  925. //
  926. m_RemoteAdminMode = FALSE;
  927. if( SUCCEEDED(hr) && NULL != pISettingComp )
  928. {
  929. hr = pISettingComp->GetTermSrvMode( &nVal, &dwStatus );
  930. if( SUCCEEDED(hr) && nVal == 0 )
  931. {
  932. // we are in RA mode
  933. m_RemoteAdminMode = TRUE;
  934. }
  935. pISettingComp->Release();
  936. }
  937. if( FAILED(hr) )
  938. {
  939. //
  940. // QueryInterface() or GetTermSrvMode() failed
  941. // bring up a error message
  942. //
  943. TCHAR tchMessage[ 256 ];
  944. TCHAR tchWarn[ 40 ];
  945. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ERR_TERMSRVMODE , tchMessage , SIZE_OF_BUFFER( tchMessage ) ) );
  946. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchWarn , SIZE_OF_BUFFER( tchWarn ) ) );
  947. MessageBox( hDlg , tchMessage , tchWarn , MB_ICONWARNING | MB_OK );
  948. }
  949. // certain operations cannot be performed if the user is not part of the admin group
  950. pCfgcomp->IsSessionReadOnly( &bReadOnly );
  951. // Set Connection name
  952. SetWindowText( GetDlgItem( hDlg , IDC_STATIC_CONNAME ) , m_pParent->m_pResNode->GetConName( ) );
  953. // List all supported lan adapters for transport type
  954. ULONG idx;
  955. if( SUCCEEDED( pCfgcomp->GetLanAdapterList2( m_pParent->m_pResNode->GetTTName() , &ulItems , &pGuidtbl ) ) )
  956. {
  957. // verify table is valid
  958. BOOL bFound = FALSE;
  959. for( idx = 0 ; idx < ulItems ; ++idx )
  960. {
  961. if( pGuidtbl[ idx ].dwStatus != ERROR_SUCCESS && !bReadOnly )
  962. {
  963. pCfgcomp->BuildGuidTable( &pGuidtbl , ulItems , m_pParent->m_pResNode->GetTTName() );
  964. break;
  965. }
  966. }
  967. for( idx = 0 ; idx < ulItems ; ++idx )
  968. {
  969. if( pGuidtbl[ idx ].dwLana == pWinSta->LanAdapter )
  970. {
  971. bFound = TRUE;
  972. break;
  973. }
  974. }
  975. if( !bFound )
  976. {
  977. if( !bReadOnly )
  978. {
  979. // Notify user we must rebuild guid table
  980. TCHAR tchMessage[ 256 ];
  981. TCHAR tchTitle[ 80 ];
  982. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_INVALNETWORK , tchMessage , SIZE_OF_BUFFER( tchMessage ) ) );
  983. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_TSCERRTITLE , tchTitle , SIZE_OF_BUFFER( tchTitle ) ) );
  984. MessageBox( hDlg , tchMessage , tchTitle , MB_OK | MB_ICONINFORMATION );
  985. m_bPersisted = FALSE;
  986. SendMessage( GetParent( hDlg ) , PSM_CHANGED , ( WPARAM )hDlg , 0 );
  987. }
  988. // reset lana index
  989. pWinSta->LanAdapter = ( DWORD )-1;
  990. }
  991. for( idx = 0 ; idx < ulItems; ++idx )
  992. {
  993. if( pGuidtbl[ idx ].dwLana == pWinSta->LanAdapter )
  994. {
  995. // make sure we only set this once
  996. // invalid entries will have dwLana set to zero
  997. if( m_ulOldLanAdapter == ( DWORD )-1 )
  998. {
  999. m_ulOldLanAdapter = idx;
  1000. }
  1001. }
  1002. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_LANADAPTER ) , CB_ADDSTRING , 0 , ( LPARAM )pGuidtbl[ idx ].DispName );
  1003. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_LANADAPTER ) , CB_SETITEMDATA , idx , ( LPARAM )pGuidtbl[ idx ].dwLana );
  1004. }
  1005. CoTaskMemFree( pGuidtbl );
  1006. }
  1007. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_LANADAPTER ) , CB_SETCURSEL , ( WPARAM )m_ulOldLanAdapter , 0 );
  1008. if( !m_bPersisted )
  1009. {
  1010. // force IsValidSettings to confirm on the lana uniqueness
  1011. m_ulOldLanAdapter = ( DWORD )-1;
  1012. }
  1013. TCHAR tchMaxConnectionsBuf[6]; // max digits
  1014. SendMessage( GetDlgItem( hDlg , IDC_EDIT_GEN_MAXCONS ) , EM_SETLIMITTEXT , SIZE_OF_BUFFER(tchMaxConnectionsBuf) , 0 );
  1015. BOOL bUnlimitedConnections = FALSE;
  1016. m_uMaxInstOld = pWinSta->uMaxInstanceCount;
  1017. if( TRUE == m_RemoteAdminMode )
  1018. {
  1019. //Display the warning icon
  1020. hIcon = LoadIcon(_Module.GetModuleInstance() , MAKEINTRESOURCE(IDI_ICON_WARNING));
  1021. hIcon = (HICON)LoadImage(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDI_ICON_WARNING), IMAGE_ICON, 0, 0, 0);
  1022. SendMessage(GetDlgItem(hDlg, IDC_USERPERM_ICON) , STM_SETICON, (WPARAM)hIcon, 0);
  1023. ShowWindow(GetDlgItem(hDlg, IDC_USERPERM_ICON), SW_SHOW);
  1024. //Display the warning text
  1025. ShowWindow(GetDlgItem(hDlg, IDC_TSMSTATIC_RA), SW_SHOW);
  1026. //Limit the max connections to 2
  1027. wsprintf(tchMaxConnectionsBuf, L"%d" ,
  1028. (pWinSta->uMaxInstanceCount > 2 || pWinSta->uMaxInstanceCount == (ULONG) -1) ? 2 : pWinSta->uMaxInstanceCount);
  1029. SendMessage(GetDlgItem(hDlg , IDC_SPINCTR_GEN), UDM_SETRANGE32, 0, (LPARAM)2);
  1030. //Unlimited connections isn't an option
  1031. bUnlimitedConnections = FALSE;
  1032. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_GEN_UNLIMITED), FALSE);
  1033. }
  1034. else
  1035. {
  1036. bUnlimitedConnections = (pWinSta->uMaxInstanceCount == (ULONG)-1);
  1037. //Set the max number of connections
  1038. wsprintf(tchMaxConnectionsBuf, L"%d", pWinSta->uMaxInstanceCount);
  1039. }
  1040. //If we're in read only mode, the NIC selector control should be disabled
  1041. if(bReadOnly)
  1042. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_GEN_LANADAPTER), FALSE);
  1043. //If we're in read only mode or a global policy exists, the user shouldn't
  1044. //be able to change the max number of connections
  1045. POLICY_TS_MACHINE p;
  1046. RegGetMachinePolicy(&p);
  1047. if (bReadOnly || p.fPolicyMaxInstanceCount)
  1048. {
  1049. //Disable the radio buttons
  1050. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_GEN_UNLIMITED), FALSE);
  1051. EnableWindow(GetDlgItem(hDlg, IDC_RADIO_MAXPROP), FALSE);
  1052. // if user have only read access, disable MAX connection and its associated spin control
  1053. EnableWindow(GetDlgItem(hDlg, IDC_EDIT_GEN_MAXCONS), FALSE);
  1054. EnableWindow(GetDlgItem(hDlg, IDC_SPINCTR_GEN), FALSE);
  1055. }
  1056. if (!bUnlimitedConnections)
  1057. {
  1058. m_oldID = IDC_RADIO_MAXPROP;
  1059. SetWindowText(GetDlgItem(hDlg, IDC_EDIT_GEN_MAXCONS), tchMaxConnectionsBuf);
  1060. }
  1061. else
  1062. {
  1063. m_oldID = IDC_CHECK_GEN_UNLIMITED;
  1064. EnableWindow(GetDlgItem(hDlg, IDC_EDIT_GEN_MAXCONS), FALSE);
  1065. EnableWindow(GetDlgItem(hDlg, IDC_SPINCTR_GEN), FALSE);
  1066. }
  1067. //Select the appropriate radio button
  1068. SendMessage(GetDlgItem(hDlg, IDC_CHECK_GEN_UNLIMITED), BM_SETCHECK, (WPARAM)(bUnlimitedConnections), 0);
  1069. SendMessage(GetDlgItem(hDlg, IDC_RADIO_MAXPROP), BM_SETCHECK, (WPARAM)(!bUnlimitedConnections), 0);
  1070. CoTaskMemFree( pWinSta );
  1071. pCfgcomp->Release( );
  1072. }while( 0 );
  1073. m_bPersisted = TRUE;
  1074. return CDialogPropBase::OnInitDialog( hDlg , wp , lp );
  1075. }
  1076. //-----------------------------------------------------------------------------
  1077. BOOL CTransNetwork::GetPropertySheetPage( PROPSHEETPAGE& psp )
  1078. {
  1079. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  1080. psp.dwSize = sizeof( PROPSHEETPAGE );
  1081. psp.dwFlags = PSP_DEFAULT;
  1082. psp.hInstance = _Module.GetResourceInstance( );
  1083. psp.pszTemplate = MAKEINTRESOURCE( IDD_NETWORK_FACE );
  1084. psp.lParam = ( LPARAM )this;
  1085. psp.pfnDlgProc = CTransNetwork::DlgProc;
  1086. return TRUE;
  1087. }
  1088. //-----------------------------------------------------------------------------
  1089. BOOL CTransNetwork::OnDestroy( )
  1090. {
  1091. m_pParent->Release( );
  1092. return CDialogPropBase::OnDestroy( );
  1093. }
  1094. //-----------------------------------------------------------------------------
  1095. BOOL CTransNetwork::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  1096. {
  1097. if( wNotifyCode == BN_CLICKED || wNotifyCode == EN_CHANGE )// || wNotifyCode == CBN_SELCHANGE )
  1098. {
  1099. if( wID == IDC_CHECK_GEN_UNLIMITED )
  1100. {
  1101. EnableWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_EDIT_GEN_MAXCONS ) ,
  1102. SendMessage( hwndCtrl , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED );
  1103. EnableWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_SPINCTR_GEN ) ,
  1104. SendMessage( hwndCtrl , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED );
  1105. SendMessage(GetDlgItem(GetParent(hwndCtrl), IDC_RADIO_MAXPROP),BM_SETCHECK,(WPARAM)BST_UNCHECKED,0);
  1106. }
  1107. else if(wID == IDC_RADIO_MAXPROP)
  1108. {
  1109. EnableWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_EDIT_GEN_MAXCONS ) ,
  1110. SendMessage( hwndCtrl , BM_GETCHECK , 0 , 0 ) == BST_CHECKED );
  1111. EnableWindow( GetDlgItem( GetParent( hwndCtrl ) , IDC_SPINCTR_GEN ) ,
  1112. SendMessage( hwndCtrl , BM_GETCHECK , 0 , 0 ) == BST_CHECKED );
  1113. SendMessage(GetDlgItem(GetParent(hwndCtrl), IDC_CHECK_GEN_UNLIMITED),BM_SETCHECK,(WPARAM)BST_UNCHECKED,0);
  1114. SetFocus( GetDlgItem( GetParent( hwndCtrl ) , IDC_EDIT_GEN_MAXCONS ) );
  1115. SendMessage( GetDlgItem( GetParent( hwndCtrl ) , IDC_EDIT_GEN_MAXCONS ) , EM_SETSEL , ( WPARAM )0 , ( LPARAM )-1 );
  1116. }
  1117. if ((wID == IDC_CHECK_GEN_UNLIMITED) || (wID == IDC_RADIO_MAXPROP))
  1118. {
  1119. if( wID != m_oldID )
  1120. {
  1121. m_bPersisted = FALSE;
  1122. m_oldID = wID;
  1123. }
  1124. }
  1125. if (wID == IDC_EDIT_GEN_MAXCONS)
  1126. m_bPersisted = FALSE;
  1127. }
  1128. else if( wNotifyCode == CBN_SELCHANGE )
  1129. {
  1130. INT_PTR iSel = SendMessage( hwndCtrl , CB_GETCURSEL , 0 , 0 );
  1131. if( iSel != ( INT_PTR )m_ulOldLanAdapter )
  1132. {
  1133. m_bPersisted = FALSE;
  1134. }
  1135. }
  1136. else if( wNotifyCode == ALN_APPLY )
  1137. {
  1138. SendMessage( GetParent( hwndCtrl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  1139. return FALSE;
  1140. }
  1141. if( !m_bPersisted )
  1142. {
  1143. SendMessage( GetParent( GetParent( hwndCtrl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtrl ) , 0 );
  1144. }
  1145. return FALSE;
  1146. }
  1147. //-----------------------------------------------------------------------------
  1148. BOOL CTransNetwork::PersistSettings( HWND hDlg )
  1149. {
  1150. BOOL bOk = FALSE;
  1151. if( IsValidSettings( hDlg ) )
  1152. {
  1153. ICfgComp *pCfgcomp;
  1154. bOk = TRUE;
  1155. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  1156. {
  1157. return FALSE;
  1158. }
  1159. WS winsta;
  1160. ZeroMemory( &winsta , sizeof( WS ) );
  1161. //If a group policy exists, its data will be in the winsta structure. We don't want to write that to
  1162. //the TSCC registry, so read the TSCC data by getting the User Config without merging the machine policy
  1163. POLICY_TS_MACHINE p;
  1164. RegGetMachinePolicy(&p);
  1165. if (p.fPolicyMaxInstanceCount)
  1166. {
  1167. POLICY_TS_MACHINE pTemp;
  1168. ULONG Length = 0;
  1169. WINSTATIONCONFIG2W WSConfig;
  1170. memset(&pTemp, 0, sizeof(POLICY_TS_MACHINE));
  1171. if((ERROR_SUCCESS != RegWinStationQueryEx(NULL,&pTemp,m_pParent->m_pResNode->GetConName( ),&WSConfig,sizeof(WINSTATIONCONFIG2W),&Length,FALSE)))
  1172. return FALSE;
  1173. winsta.uMaxInstanceCount = WSConfig.Create.MaxInstanceCount;
  1174. }
  1175. else
  1176. {
  1177. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_GEN_UNLIMITED ), BM_GETCHECK , 0 , 0 ) == BST_CHECKED )
  1178. winsta.uMaxInstanceCount = ( ULONG )-1;
  1179. else
  1180. winsta.uMaxInstanceCount = GetDlgItemInt( hDlg , IDC_EDIT_GEN_MAXCONS , &bOk , FALSE );
  1181. }
  1182. INT_PTR iSel = SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_LANADAPTER ) , CB_GETCURSEL , 0 , 0 );
  1183. winsta.LanAdapter = ( ULONG )SendMessage(
  1184. GetDlgItem( hDlg , IDC_COMBO_GEN_LANADAPTER ) ,
  1185. CB_GETITEMDATA ,
  1186. ( WPARAM )iSel ,
  1187. 0 );
  1188. if( iSel != CB_ERR )
  1189. {
  1190. if( iSel != ( INT_PTR )m_ulOldLanAdapter )
  1191. {
  1192. LONG lCount;
  1193. pCfgcomp->QueryLoggedOnCount( m_pParent->m_pResNode->GetConName( ) , &lCount );
  1194. if( lCount > 0 )
  1195. {
  1196. // Warn user, changing an active lan adapter will cause all connections to disconnect
  1197. TCHAR tchMessage[ 256 ];
  1198. TCHAR tchWarn[ 40 ];
  1199. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ERR_LANCHANGE , tchMessage , SIZE_OF_BUFFER( tchMessage ) ) );
  1200. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchWarn , SIZE_OF_BUFFER( tchWarn ) ) );
  1201. if( MessageBox( hDlg , tchMessage , tchWarn , MB_ICONWARNING | MB_YESNO ) == IDNO )
  1202. {
  1203. bOk = FALSE;
  1204. }
  1205. }
  1206. }
  1207. }
  1208. if( bOk && iSel != CB_ERR )
  1209. {
  1210. lstrcpyn( winsta.Name , m_pParent->m_pResNode->GetConName( ) , SIZE_OF_BUFFER( winsta.Name ) - 1 );
  1211. DWORD dwStatus;
  1212. DWORD dwUpdateFlags = UPDATE_LANADAPTER;
  1213. if (!p.fPolicyMaxInstanceCount)
  1214. dwUpdateFlags |= UPDATE_MAXINSTANCECOUNT;
  1215. if( FAILED( pCfgcomp->UpDateWS( &winsta , dwUpdateFlags , &dwStatus, FALSE ) ) )
  1216. {
  1217. // report error and get out
  1218. ReportStatusError( hDlg , dwStatus );
  1219. pCfgcomp->Release( );
  1220. }
  1221. else
  1222. {
  1223. ODS( L"Connection LANA persisted\n" );
  1224. m_ulOldLanAdapter = ( ULONG )iSel;
  1225. ODS( L"TSCC : Forcing reg update - CTransNetwork\n" );
  1226. VERIFY_S( S_OK , pCfgcomp->ForceUpdate( ) );
  1227. VERIFY_S( S_OK , pCfgcomp->Refresh( ) );
  1228. // global flag can only be set to true
  1229. m_pParent->m_bPropertiesChange = TRUE;
  1230. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  1231. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  1232. }
  1233. }
  1234. pCfgcomp->Release( );
  1235. }
  1236. return bOk;
  1237. }
  1238. //-----------------------------------------------------------------------------
  1239. BOOL CTransNetwork::IsValidSettings( HWND hDlg )
  1240. {
  1241. BOOL ret = TRUE;
  1242. ICfgComp *pCfgcomp;
  1243. TCHAR tchMessage[ 256 ];
  1244. TCHAR tchWarn[ 40 ];
  1245. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_GEN_UNLIMITED ), BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED )
  1246. {
  1247. UINT uMax;
  1248. BOOL bOK = FALSE;
  1249. uMax = GetDlgItemInt( hDlg , IDC_EDIT_GEN_MAXCONS , &bOK , FALSE );
  1250. if( !bOK )
  1251. {
  1252. ErrMessage( hDlg , IDS_ERR_CONREADFAIL );
  1253. SetFocus( GetDlgItem( hDlg , IDC_EDIT_GEN_MAXCONS ) );
  1254. SendMessage( GetDlgItem( hDlg , IDC_EDIT_GEN_MAXCONS ) , EM_SETSEL , ( WPARAM )0 , ( LPARAM )-1 );
  1255. return FALSE;
  1256. }
  1257. if( uMax > 999999UL )
  1258. {
  1259. ErrMessage( hDlg , IDS_ERR_CONMAX );
  1260. SetFocus( GetDlgItem( hDlg , IDC_EDIT_GEN_MAXCONS ) );
  1261. SendMessage( GetDlgItem( hDlg , IDC_EDIT_GEN_MAXCONS ) , EM_SETSEL , ( WPARAM )0 , ( LPARAM )-1 );
  1262. return FALSE;
  1263. }
  1264. }
  1265. if( m_pParent != NULL && m_pParent->m_pResNode != NULL )
  1266. {
  1267. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  1268. {
  1269. return FALSE;
  1270. }
  1271. // PDNAMEW pName;
  1272. PWS pWinSta;
  1273. LONG cbSize;
  1274. if( SUCCEEDED( pCfgcomp->GetWSInfo( m_pParent->m_pResNode->GetConName( ) , ( PLONG )&cbSize , &pWinSta ) ) )
  1275. {
  1276. INT_PTR iSel = SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_LANADAPTER ) , CB_GETCURSEL , 0 , 0 );
  1277. BOOL bUnique = TRUE;
  1278. if( iSel != CB_ERR )
  1279. {
  1280. if( iSel != ( int )m_ulOldLanAdapter )
  1281. {
  1282. ULONG nStations;
  1283. VERIFY_S( S_OK , pCfgcomp->GetNumofWinStations(pWinSta->wdName,pWinSta->pdName,&nStations ) );
  1284. DBGMSG( L"TSCC: Number of winstations equals = %d\n" , nStations );
  1285. if( nStations > 1 )
  1286. {
  1287. ODS( L"TSCC: We have more than one winstation verify unique lana settings\n" );
  1288. ULONG ulLana = ( ULONG )SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_LANADAPTER ) , CB_GETITEMDATA , ( WPARAM )iSel , 0 );
  1289. VERIFY_S( S_OK , pCfgcomp->IsNetWorkConnectionUnique( m_pParent->m_pResNode->GetTypeName( ) , pWinSta->pdName , ulLana , &bUnique ) );
  1290. }
  1291. if( !bUnique )
  1292. {
  1293. //ErrMessage( hDlg , IDS_ERR_UNIQUECON );
  1294. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ERR_UNIQUECON , tchMessage , SIZE_OF_BUFFER( tchMessage ) ) );
  1295. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchWarn , SIZE_OF_BUFFER( tchWarn ) ) );
  1296. MessageBox( hDlg , tchMessage , tchWarn , MB_ICONINFORMATION | MB_OK );
  1297. ret = FALSE;
  1298. }
  1299. else
  1300. {
  1301. LONG lCount;
  1302. pCfgcomp->QueryLoggedOnCount( m_pParent->m_pResNode->GetConName( ) , &lCount );
  1303. if( lCount > 0 )
  1304. {
  1305. // Warn user, changing an active lan adapter will cause all connections to disconnect
  1306. TCHAR tchMessage[ 256 ];
  1307. TCHAR tchWarn[ 40 ];
  1308. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ERR_LANCHANGE , tchMessage , SIZE_OF_BUFFER( tchMessage ) ) );
  1309. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchWarn , SIZE_OF_BUFFER( tchWarn ) ) );
  1310. if( MessageBox( hDlg , tchMessage , tchWarn , MB_ICONWARNING | MB_YESNO ) == IDNO )
  1311. {
  1312. ret = FALSE;
  1313. }
  1314. }
  1315. }
  1316. if( ret )
  1317. {
  1318. m_ulOldLanAdapter = (ULONG)iSel;
  1319. }
  1320. }
  1321. }
  1322. CoTaskMemFree( pWinSta );
  1323. }
  1324. pCfgcomp->Release( );
  1325. }
  1326. if( !ret )
  1327. {
  1328. if( m_uMaxInstOld == ( ULONG )-1 )
  1329. {
  1330. EnableWindow( GetDlgItem( hDlg , IDC_EDIT_GEN_MAXCONS ) , FALSE );
  1331. EnableWindow( GetDlgItem( hDlg , IDC_SPINCTR_GEN ) , FALSE );
  1332. SendMessage( GetDlgItem( hDlg , IDC_CHECK_GEN_UNLIMITED ) , BM_CLICK , 0 , 0 );
  1333. m_oldID = IDC_CHECK_GEN_UNLIMITED;
  1334. }
  1335. else
  1336. {
  1337. TCHAR tchBuf[ 16 ];
  1338. EnableWindow( GetDlgItem( hDlg , IDC_EDIT_GEN_MAXCONS ) , TRUE );
  1339. EnableWindow( GetDlgItem( hDlg , IDC_SPINCTR_GEN ) , TRUE );
  1340. wsprintf( tchBuf , L"%d" , m_uMaxInstOld );
  1341. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_GEN_MAXCONS ) , tchBuf );
  1342. SendMessage( GetDlgItem( hDlg , IDC_RADIO_MAXPROP) , BM_CLICK , 0 , 0 );
  1343. m_oldID = IDC_RADIO_MAXPROP;
  1344. }
  1345. SendMessage( GetDlgItem( hDlg , IDC_COMBO_GEN_LANADAPTER ) , CB_SETCURSEL , ( WPARAM )m_ulOldLanAdapter , 0 );
  1346. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  1347. m_bPersisted = TRUE;
  1348. }
  1349. return ret;
  1350. }
  1351. //*****************************************************************************
  1352. CTransAsync::CTransAsync( CPropsheet * pSheet )
  1353. {
  1354. m_pParent = pSheet;
  1355. }
  1356. //-----------------------------------------------------------------------------
  1357. BOOL CTransAsync::OnInitDialog( HWND hwnd , WPARAM wp , LPARAM lp )
  1358. {
  1359. ICfgComp *pCfgcomp = NULL;
  1360. m_pParent->AddRef( );
  1361. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  1362. {
  1363. ODS( L"Cound not obtain backend interface @ CTransAsync::OnInitDialog\n" );
  1364. return FALSE;
  1365. }
  1366. VERIFY_S( TRUE , m_pParent->GetCurrentUserConfig( m_uc, TRUE ) );
  1367. pCfgcomp->GetAsyncConfig( m_pParent->m_pResNode->GetConName() , WsName , &m_ac );
  1368. VERIFY_S( TRUE , CAsyncDlg::OnInitDialog( hwnd , m_pParent->m_pResNode->GetTypeName( ) , m_pParent->m_pResNode->GetConName( ) , pCfgcomp ) ) ;
  1369. BOOL bReadOnly;
  1370. if( SUCCEEDED( pCfgcomp->IsSessionReadOnly( &bReadOnly ) ) )
  1371. {
  1372. if( bReadOnly )
  1373. {
  1374. // disable the remaining controls
  1375. INT rgIds[] = {
  1376. IDC_ASYNC_DEVICENAME,
  1377. IDC_ASYNC_CONNECT,
  1378. IDC_ASYNC_BAUDRATE,
  1379. IDC_ASYNC_MODEMCALLBACK_PHONENUMBER,
  1380. IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT,
  1381. IDC_ASYNC_MODEMCALLBACK,
  1382. IDC_ASYNC_MODEMCALLBACK_INHERIT,
  1383. IDC_MODEM_PROP_PROP,
  1384. IDC_ASYNC_DEFAULTS,
  1385. IDC_ASYNC_ADVANCED,
  1386. IDC_ASYNC_TEST, -1
  1387. };
  1388. EnableGroup( hwnd , &rgIds[ 0 ] , FALSE );
  1389. }
  1390. }
  1391. pCfgcomp->Release( );
  1392. m_bPersisted = TRUE;
  1393. return CDialogPropBase::OnInitDialog( hwnd , wp , lp );
  1394. }
  1395. //-----------------------------------------------------------------------------
  1396. INT_PTR CALLBACK CTransAsync::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  1397. {
  1398. CTransAsync *pDlg;
  1399. if( msg == WM_INITDIALOG )
  1400. {
  1401. CTransAsync *pDlg = ( CTransAsync * )( ( PROPSHEETPAGE *)lp )->lParam ;
  1402. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  1403. if( !IsBadReadPtr( pDlg , sizeof( CTransAsync ) ) )
  1404. {
  1405. pDlg->OnInitDialog( hwnd , wp , lp );
  1406. }
  1407. return 0;
  1408. }
  1409. else
  1410. {
  1411. pDlg = ( CTransAsync * )GetWindowLongPtr( hwnd , DWLP_USER );
  1412. if( IsBadReadPtr( pDlg , sizeof( CTransAsync ) ) )
  1413. {
  1414. return FALSE;
  1415. }
  1416. }
  1417. switch( msg )
  1418. {
  1419. case WM_NCDESTROY:
  1420. pDlg->OnDestroy( );
  1421. break;
  1422. case WM_COMMAND:
  1423. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  1424. break;
  1425. case WM_CONTEXTMENU:
  1426. {
  1427. POINT pt;
  1428. pt.x = LOWORD( lp );
  1429. pt.y = HIWORD( lp );
  1430. pDlg->OnContextMenu( ( HWND )wp , pt );
  1431. }
  1432. break;
  1433. case WM_HELP:
  1434. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  1435. break;
  1436. case WM_NOTIFY:
  1437. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  1438. }
  1439. return FALSE;
  1440. }
  1441. //-----------------------------------------------------------------------------
  1442. BOOL CTransAsync::GetPropertySheetPage( PROPSHEETPAGE& psp )
  1443. {
  1444. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  1445. psp.dwSize = sizeof( PROPSHEETPAGE );
  1446. psp.dwFlags = PSP_DEFAULT;
  1447. psp.hInstance = _Module.GetResourceInstance( );
  1448. psp.pszTemplate = MAKEINTRESOURCE( IDD_ASYNC_FACE );
  1449. psp.lParam = ( LPARAM )this;
  1450. psp.pfnDlgProc = CTransAsync::DlgProc;
  1451. return TRUE;
  1452. }
  1453. //-----------------------------------------------------------------------------
  1454. BOOL CTransAsync::OnDestroy( )
  1455. {
  1456. AsyncRelease( );
  1457. m_pParent->Release( );
  1458. return CDialogPropBase::OnDestroy( );
  1459. }
  1460. //-----------------------------------------------------------------------------
  1461. BOOL CTransAsync::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  1462. {
  1463. CAsyncDlg::OnCommand( wNotifyCode , wID , hwndCtrl , &m_bPersisted );
  1464. if( wNotifyCode == ALN_APPLY )
  1465. {
  1466. SendMessage( GetParent( hwndCtrl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  1467. return FALSE;
  1468. }
  1469. if( !m_bPersisted )
  1470. {
  1471. SendMessage( GetParent( GetParent( hwndCtrl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtrl ) , 0 );
  1472. }
  1473. return FALSE;
  1474. }
  1475. //-----------------------------------------------------------------------------
  1476. BOOL CTransAsync::PersistSettings( HWND hDlg )
  1477. {
  1478. if( !IsValidSettings( hDlg ) )
  1479. {
  1480. return FALSE;
  1481. }
  1482. ICfgComp * pCfgcomp = NULL;
  1483. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  1484. {
  1485. ODS( L"Cound not obtain backend interface @ CTransAsync::OnInitDialog\n" );
  1486. return FALSE;
  1487. }
  1488. DWORD dwStatus;
  1489. HRESULT hr = pCfgcomp->SetAsyncConfig( m_pParent->m_pResNode->GetConName() , WsName , &m_ac , &dwStatus );
  1490. if( FAILED( hr ) )
  1491. {
  1492. ReportStatusError( hDlg , dwStatus );
  1493. }
  1494. if( SUCCEEDED( hr ) )
  1495. {
  1496. DWORD dwStatus;
  1497. hr = m_pParent->SetUserConfig( m_uc , &dwStatus );
  1498. if( FAILED( hr ) )
  1499. {
  1500. ReportStatusError( hDlg , dwStatus );
  1501. }
  1502. }
  1503. if( SUCCEEDED( hr ) )
  1504. {
  1505. ODS( L"TSCC : Forcing reg update - CTransAsync\n" );
  1506. VERIFY_S( S_OK , pCfgcomp->ForceUpdate( ) );
  1507. VERIFY_S( S_OK , pCfgcomp->Refresh( ) );
  1508. // global flag can only be set to true
  1509. m_pParent->m_bPropertiesChange = TRUE;
  1510. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  1511. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  1512. }
  1513. pCfgcomp->Release( );
  1514. return SUCCEEDED( hr ) ? TRUE : FALSE;
  1515. }
  1516. BOOL CTransAsync::IsValidSettings(HWND hDlg)
  1517. {
  1518. UNREFERENCED_PARAMETER( hDlg );
  1519. // all async connections are checked for usage
  1520. // thus no two connections can use the same port
  1521. return TRUE;
  1522. }
  1523. //*****************************************************************************
  1524. // Logon settings dialog
  1525. CLogonSetting::CLogonSetting( CPropsheet *pSheet )
  1526. {
  1527. m_pParent = pSheet;
  1528. m_wOldId = ( WORD )-1;
  1529. }
  1530. //-----------------------------------------------------------------------------
  1531. BOOL CLogonSetting::OnInitDialog( HWND hDlg , WPARAM wp , LPARAM lp )
  1532. {
  1533. if( !IsBadReadPtr( m_pParent , sizeof( CPropsheet ) ) )
  1534. {
  1535. m_pParent->AddRef( );
  1536. }
  1537. USERCONFIG uc;
  1538. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  1539. {
  1540. ODS( L"CLogonSetting::OnInitDialog - GetCurrentUserConfig failed!!!\n" );
  1541. return FALSE;
  1542. }
  1543. /*
  1544. SendMessage( GetDlgItem( hDlg , IDC_CHECK_LOGON_INHERIT ) , BM_SETCHECK ,
  1545. uc.fInheritAutoLogon ? BST_CHECKED : BST_UNCHECKED , 0 );*/
  1546. if( uc.fInheritAutoLogon == BST_CHECKED )
  1547. {
  1548. CheckRadioButton( hDlg , IDC_CHECK_LOGON_INHERIT , IDC_RADIO_LOGON , IDC_CHECK_LOGON_INHERIT );
  1549. m_wOldId = IDC_CHECK_LOGON_INHERIT;
  1550. }
  1551. else
  1552. {
  1553. CheckRadioButton( hDlg , IDC_CHECK_LOGON_INHERIT , IDC_RADIO_LOGON , IDC_RADIO_LOGON );
  1554. m_wOldId = IDC_RADIO_LOGON;
  1555. }
  1556. SendMessage( GetDlgItem( hDlg , IDC_CHECK_LOGON_PROMPTPASSWD ), BM_SETCHECK ,
  1557. uc.fPromptForPassword ? BST_CHECKED : BST_UNCHECKED , 0 );
  1558. POLICY_TS_MACHINE p;
  1559. RegGetMachinePolicy(&p);
  1560. EnableWindow( GetDlgItem( hDlg, IDC_CHECK_LOGON_PROMPTPASSWD ), !p.fPolicyPromptForPassword);
  1561. //int rgID[] = { IDC_EDIT_LOGON_USRNAME , IDC_EDIT_LOGON_DOMAIN , IDC_EDIT_LOGON_PASSWD , IDC_EDIT_LOGON_CONFIRMPASSWD , -1 };
  1562. SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOGON_USRNAME ) , EM_SETLIMITTEXT , ( WPARAM )USERNAME_LENGTH , 0 );
  1563. SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOGON_DOMAIN ) , EM_SETLIMITTEXT , ( WPARAM )DOMAIN_LENGTH , 0 );
  1564. SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOGON_PASSWD ) , EM_SETLIMITTEXT , ( WPARAM )PASSWORD_LENGTH , 0 );
  1565. SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOGON_CONFIRMPASSWD ) , EM_SETLIMITTEXT , ( WPARAM )PASSWORD_LENGTH , 0 );
  1566. if( !uc.fInheritAutoLogon )
  1567. {
  1568. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_USRNAME ) , ( LPTSTR )uc.UserName );
  1569. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_DOMAIN ) , ( LPTSTR )uc.Domain );
  1570. }
  1571. if( !uc.fPromptForPassword )
  1572. {
  1573. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_PASSWD ) , ( LPTSTR )uc.Password );
  1574. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_CONFIRMPASSWD ) , ( LPTSTR )uc.Password );
  1575. }
  1576. int rgID[] = { IDC_EDIT_LOGON_USRNAME , IDC_STATIC_LSUSR , IDC_EDIT_LOGON_DOMAIN , IDC_STATIC_LSDOMAIN , IDC_EDIT_LOGON_PASSWD , IDC_STATIC_LSPWD , IDC_EDIT_LOGON_CONFIRMPASSWD , IDC_STATIC_LSCONPWD , -1 };
  1577. EnableGroup( hDlg , &rgID[0] , !uc.fInheritAutoLogon );
  1578. if( !uc.fInheritAutoLogon )
  1579. {
  1580. EnableGroup( hDlg , &rgID[4] , !uc.fPromptForPassword );
  1581. }
  1582. ICfgComp *pCfgcomp = NULL;
  1583. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) != 0 )
  1584. {
  1585. BOOL bReadOnly;
  1586. if( SUCCEEDED( pCfgcomp->IsSessionReadOnly( &bReadOnly ) ) )
  1587. {
  1588. if( bReadOnly )
  1589. {
  1590. // make edit controls read-only
  1591. SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOGON_USRNAME ) , EM_SETREADONLY , ( WPARAM )TRUE , 0 );
  1592. SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOGON_DOMAIN ) , EM_SETREADONLY , ( WPARAM )TRUE , 0 );
  1593. // disable the remaining controls
  1594. INT rgIds[] = {
  1595. IDC_EDIT_LOGON_PASSWD,
  1596. IDC_EDIT_LOGON_CONFIRMPASSWD,
  1597. IDC_CHECK_LOGON_PROMPTPASSWD,
  1598. IDC_CHECK_LOGON_INHERIT,
  1599. IDC_RADIO_LOGON,
  1600. -1
  1601. };
  1602. EnableGroup( hDlg , &rgIds[ 0 ] , FALSE );
  1603. }
  1604. }
  1605. pCfgcomp->Release( );
  1606. }
  1607. m_bPersisted = TRUE;
  1608. return CDialogPropBase::OnInitDialog( hDlg , wp , lp );
  1609. }
  1610. //-----------------------------------------------------------------------------
  1611. INT_PTR CALLBACK CLogonSetting::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  1612. {
  1613. CLogonSetting *pDlg;
  1614. if( msg == WM_INITDIALOG )
  1615. {
  1616. CLogonSetting *pDlg = ( CLogonSetting * )( ( PROPSHEETPAGE *)lp )->lParam ;
  1617. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  1618. if( !IsBadReadPtr( pDlg , sizeof( CLogonSetting ) ) )
  1619. {
  1620. pDlg->OnInitDialog( hwnd , wp , lp );
  1621. }
  1622. return 0;
  1623. }
  1624. else
  1625. {
  1626. pDlg = ( CLogonSetting * )GetWindowLongPtr( hwnd , DWLP_USER );
  1627. if( IsBadReadPtr( pDlg , sizeof( CLogonSetting ) ) )
  1628. {
  1629. return FALSE;
  1630. }
  1631. }
  1632. switch( msg )
  1633. {
  1634. case WM_NCDESTROY:
  1635. pDlg->OnDestroy( );
  1636. break;
  1637. case WM_COMMAND:
  1638. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  1639. break;
  1640. case WM_CONTEXTMENU:
  1641. {
  1642. POINT pt;
  1643. pt.x = LOWORD( lp );
  1644. pt.y = HIWORD( lp );
  1645. pDlg->OnContextMenu( ( HWND )wp , pt );
  1646. }
  1647. break;
  1648. case WM_HELP:
  1649. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  1650. break;
  1651. case WM_NOTIFY:
  1652. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  1653. }
  1654. return 0;
  1655. }
  1656. //-----------------------------------------------------------------------------
  1657. BOOL CLogonSetting::GetPropertySheetPage( PROPSHEETPAGE& psp )
  1658. {
  1659. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  1660. psp.dwSize = sizeof( PROPSHEETPAGE );
  1661. psp.dwFlags = PSP_DEFAULT;
  1662. psp.hInstance = _Module.GetResourceInstance( );
  1663. psp.pszTemplate = MAKEINTRESOURCE( IDD_LOGONSETTINGS );
  1664. psp.lParam = ( LPARAM )this;
  1665. psp.pfnDlgProc = CLogonSetting::DlgProc;
  1666. return TRUE;
  1667. }
  1668. //---------------------------------------------------------------------------
  1669. BOOL CLogonSetting::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  1670. {
  1671. if( wNotifyCode == BN_CLICKED )
  1672. {
  1673. int rgID[] = { IDC_EDIT_LOGON_USRNAME , IDC_STATIC_LSUSR , IDC_EDIT_LOGON_DOMAIN , IDC_STATIC_LSDOMAIN , IDC_EDIT_LOGON_PASSWD , IDC_STATIC_LSPWD , IDC_EDIT_LOGON_CONFIRMPASSWD , IDC_STATIC_LSCONPWD , -1 };
  1674. BOOL bEnable = ( BOOL )SendMessage( GetDlgItem( GetParent( hwndCtrl ) , IDC_CHECK_LOGON_INHERIT ) , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED;
  1675. if( wID == IDC_CHECK_LOGON_INHERIT )
  1676. {
  1677. EnableGroup( GetParent( hwndCtrl ) , &rgID[ 0 ] , bEnable );
  1678. if( bEnable )
  1679. {
  1680. EnableGroup( GetParent( hwndCtrl ) , &rgID[ 4 ] , SendMessage( GetDlgItem( GetParent( hwndCtrl ) , IDC_CHECK_LOGON_PROMPTPASSWD ) , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED );
  1681. SendMessage(GetDlgItem(GetParent(hwndCtrl), IDC_RADIO_LOGON),BM_SETCHECK,(WPARAM)BST_CHECKED,0);
  1682. }
  1683. else
  1684. {
  1685. SendMessage(GetDlgItem(GetParent(hwndCtrl), IDC_RADIO_LOGON),BM_SETCHECK,(WPARAM)BST_UNCHECKED,0);
  1686. }
  1687. }
  1688. else if( wID == IDC_CHECK_LOGON_PROMPTPASSWD )
  1689. {
  1690. if( bEnable )
  1691. {
  1692. EnableGroup( GetParent( hwndCtrl ) , &rgID[ 4 ] , SendMessage( hwndCtrl , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED );
  1693. }
  1694. // make sure apply button becomes enabled when user checks this box
  1695. m_bPersisted = FALSE;
  1696. }
  1697. else if( wID == IDC_RADIO_LOGON )
  1698. {
  1699. BOOL bChecked = SendMessage( hwndCtrl , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ;
  1700. if(bChecked)
  1701. {
  1702. //SendMessage(GetDlgItem(GetParent(hwndCtrl), IDC_CHECK_LOGON_INHERIT),BM_SETCHECK,(WPARAM)BST_UNCHECKED,0);
  1703. EnableGroup( GetParent( hwndCtrl ) , &rgID[ 0 ] , TRUE );
  1704. EnableGroup( GetParent( hwndCtrl ) , &rgID[ 4 ] , !( SendMessage( GetDlgItem( GetParent( hwndCtrl ) , IDC_CHECK_LOGON_PROMPTPASSWD ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ) );
  1705. }
  1706. else
  1707. {
  1708. SendMessage(GetDlgItem(GetParent(hwndCtrl), IDC_CHECK_LOGON_INHERIT),BM_SETCHECK,(WPARAM)BST_CHECKED,0);
  1709. }
  1710. //SendMessage(GetDlgItem(GetParent(hwndCtrl), IDC_CHECK_ICCP_WZ),BM_CLICK,0,0);
  1711. }
  1712. // if radio button from the last is different enabled the apply button
  1713. if( m_wOldId != wID )
  1714. {
  1715. m_wOldId = wID;
  1716. m_bPersisted = FALSE;
  1717. }
  1718. }
  1719. else if( wNotifyCode == EN_CHANGE )
  1720. {
  1721. m_bPersisted = FALSE;
  1722. }
  1723. else if( wNotifyCode == ALN_APPLY )
  1724. {
  1725. SendMessage( GetParent( hwndCtrl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  1726. return FALSE;
  1727. }
  1728. if( !m_bPersisted )
  1729. {
  1730. SendMessage( GetParent( GetParent( hwndCtrl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtrl ) , 0 );
  1731. }
  1732. return FALSE;
  1733. }
  1734. //-----------------------------------------------------------------------------
  1735. BOOL CLogonSetting::OnDestroy( )
  1736. {
  1737. m_pParent->Release( );
  1738. return CDialogPropBase::OnDestroy( );
  1739. }
  1740. //-----------------------------------------------------------------------------
  1741. BOOL CLogonSetting::PersistSettings( HWND hDlg )
  1742. {
  1743. if( m_pParent != NULL )
  1744. {
  1745. USERCONFIG uc;
  1746. m_pParent->GetCurrentUserConfig( uc, TRUE );
  1747. uc.fPromptForPassword = SendMessage( GetDlgItem( hDlg , IDC_CHECK_LOGON_PROMPTPASSWD ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  1748. if( !uc.fPromptForPassword )
  1749. {
  1750. if( !ConfirmPassWd( hDlg ) )
  1751. {
  1752. return FALSE;
  1753. }
  1754. }
  1755. else
  1756. {
  1757. SecureZeroMemory( ( PVOID )uc.Password , sizeof( uc.Password ) );
  1758. }
  1759. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_LOGON_INHERIT ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED )
  1760. {
  1761. uc.fInheritAutoLogon = TRUE;
  1762. ZeroMemory( ( PVOID )uc.UserName , sizeof( uc.UserName ) );
  1763. ZeroMemory( ( PVOID )uc.Domain , sizeof( uc.Domain ) );
  1764. SecureZeroMemory( ( PVOID )uc.Password , sizeof( uc.Password ) );
  1765. }
  1766. else
  1767. {
  1768. uc.fInheritAutoLogon = FALSE;
  1769. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_USRNAME ) , uc.UserName , USERNAME_LENGTH + 1 );
  1770. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_DOMAIN ) , uc.Domain , DOMAIN_LENGTH + 1 );
  1771. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_PASSWD ) , uc.Password , PASSWORD_LENGTH + 1 );
  1772. }
  1773. DWORD dwStatus;
  1774. if( FAILED( m_pParent->SetUserConfig( uc , &dwStatus ) ) )
  1775. {
  1776. ReportStatusError( hDlg , dwStatus );
  1777. return FALSE;
  1778. }
  1779. ICfgComp *pCfgcomp = NULL;
  1780. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) > 0 )
  1781. {
  1782. VERIFY_S( S_OK , pCfgcomp->ForceUpdate( ) );
  1783. VERIFY_S( S_OK , pCfgcomp->Refresh( ) );
  1784. // global flag can only be set to true
  1785. m_pParent->m_bPropertiesChange = TRUE;
  1786. pCfgcomp->Release( );
  1787. }
  1788. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  1789. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  1790. return TRUE;
  1791. }
  1792. return FALSE;
  1793. }
  1794. //-----------------------------------------------------------------------------
  1795. BOOL CLogonSetting::IsValidSettings( HWND hDlg )
  1796. {
  1797. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_LOGON_PROMPTPASSWD ) , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED )
  1798. {
  1799. return ConfirmPassWd( hDlg );
  1800. }
  1801. return TRUE;
  1802. }
  1803. //-----------------------------------------------------------------------------
  1804. BOOL CLogonSetting::ConfirmPassWd( HWND hDlg )
  1805. {
  1806. TCHAR tchPzWd[ PASSWORD_LENGTH + 1];
  1807. TCHAR tchConfirm[ PASSWORD_LENGTH + 1];
  1808. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_LOGON_INHERIT ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED )
  1809. {
  1810. return TRUE;
  1811. }
  1812. int iSz = GetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_PASSWD ) , tchPzWd , PASSWORD_LENGTH + 1 );
  1813. // warn on the minimum and maximum sizes
  1814. if( iSz > PASSWORD_LENGTH ) //if( iSz > 0 && ( iSz < 6 || iSz > PASSWORD_LENGTH ) )
  1815. {
  1816. ErrMessage( hDlg , IDS_ERR_PASSWD );
  1817. // set focus back on password and erase the confirm entry
  1818. SetFocus( GetDlgItem( hDlg , IDC_EDIT_LOGON_PASSWD ) );
  1819. SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOGON_PASSWD ) , EM_SETSEL , ( WPARAM )0 , ( LPARAM )-1 );
  1820. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_CONFIRMPASSWD ) , L"" );
  1821. return FALSE;
  1822. }
  1823. int iSz2 = GetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_CONFIRMPASSWD ) , tchConfirm , PASSWORD_LENGTH + 1 );
  1824. if( iSz == iSz2 )
  1825. {
  1826. if( iSz == 0 )
  1827. {
  1828. return TRUE;
  1829. }
  1830. if( lstrcmp( tchPzWd , tchConfirm ) == 0 )
  1831. {
  1832. return TRUE;
  1833. }
  1834. }
  1835. ErrMessage( hDlg , IDS_ERR_PASSCONFIRM );
  1836. SetFocus( GetDlgItem( hDlg , IDC_EDIT_LOGON_CONFIRMPASSWD ) );
  1837. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOGON_CONFIRMPASSWD ) , L"" );
  1838. return FALSE;
  1839. }
  1840. //*****************************************************************************
  1841. // Time out settings dialog
  1842. CTimeSetting::CTimeSetting( CPropsheet *pSheet )
  1843. {
  1844. m_pParent = pSheet;
  1845. m_wOldAction = ( WORD )-1;
  1846. m_wOldCon = ( WORD )-1;
  1847. m_bPrevClient = FALSE;
  1848. }
  1849. //-----------------------------------------------------------------------------
  1850. BOOL CTimeSetting::OnInitDialog( HWND hwnd , WPARAM wp , LPARAM lp )
  1851. {
  1852. TCHAR tchBuffer[ 80 ];
  1853. if( m_pParent == NULL )
  1854. {
  1855. ODS( L"CTimeSetting::OnInitDialog - PropertySheet: We've lost our parent node!!!\n" );
  1856. return FALSE;
  1857. }
  1858. m_pParent->AddRef( );
  1859. USERCONFIG uc;
  1860. HWND hCombo[ 3 ] =
  1861. {
  1862. GetDlgItem( hwnd , IDC_COMBO_TIMEOUTS_CON_PS ),
  1863. GetDlgItem( hwnd , IDC_COMBO_TIMEOUTS_DISCON_PS ),
  1864. GetDlgItem( hwnd , IDC_COMBO_TIMEOUTS_IDLE_PS )
  1865. };
  1866. DWORD rgdwTime[] = { 0 , 1 , 5 , 10 , 15 , 30 , 60 , 120 , 180 , 1440 , 2880 , ( DWORD )-1 };
  1867. for( int idx = 0; rgdwTime[ idx ] != ( DWORD)-1; ++idx )
  1868. {
  1869. if( rgdwTime[ idx ] == 0 )
  1870. {
  1871. LoadString( _Module.GetResourceInstance( ) , IDS_NOTIMEOUT , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) );
  1872. }
  1873. else
  1874. {
  1875. ConvertToDuration( rgdwTime[ idx ] , tchBuffer );
  1876. }
  1877. for( int inner = 0 ; inner < 3 ; ++inner )
  1878. {
  1879. SendMessage( hCombo[ inner ] , CB_ADDSTRING , 0 , ( LPARAM )&tchBuffer[0] );
  1880. SendMessage( hCombo[ inner ] , CB_SETITEMDATA , idx , rgdwTime[ idx ] );
  1881. }
  1882. }
  1883. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  1884. {
  1885. ODS( L"CTimeSetting::OnInitDialog - PropertySheet: Could not get current USERCONFIG\n" );
  1886. return FALSE;
  1887. }
  1888. ULONG ulTime;
  1889. if( uc.MaxConnectionTime > 0 )
  1890. {
  1891. ulTime = uc.MaxConnectionTime / kMilliMinute;
  1892. InsertSortedAndSetCurSel( hCombo[ 0 ] , ulTime );
  1893. }
  1894. else
  1895. {
  1896. SendMessage( hCombo[ 0 ] , CB_SETCURSEL , 0 , 0 );
  1897. }
  1898. CTimeOutDlg::InitControl( hCombo[ 0 ] );
  1899. //
  1900. // Set the current or default disconnection timeout
  1901. //
  1902. if( uc.MaxDisconnectionTime > 0 )
  1903. {
  1904. ulTime = uc.MaxDisconnectionTime / kMilliMinute;
  1905. InsertSortedAndSetCurSel( hCombo[ 1 ] , ulTime );
  1906. }
  1907. else
  1908. {
  1909. SendMessage( hCombo[ 1] , CB_SETCURSEL , 0 , 0 );
  1910. }
  1911. CTimeOutDlg::InitControl( hCombo[ 1 ] );
  1912. //
  1913. // Set the current or default idle timeout
  1914. //
  1915. if( uc.MaxIdleTime > 0 )
  1916. {
  1917. ulTime = uc.MaxIdleTime / kMilliMinute;
  1918. InsertSortedAndSetCurSel( hCombo[ 2 ] , ulTime );
  1919. }
  1920. else
  1921. {
  1922. SendMessage( hCombo[ 2 ] , CB_SETCURSEL , 0 , 0 );
  1923. }
  1924. CTimeOutDlg::InitControl( hCombo[ 2 ] );
  1925. //
  1926. // all the timeout settings will have the same inherit status (NOT!)
  1927. //
  1928. // GP made all these settings orthogonal. When we write son of TSCC
  1929. // in Blackcomb, we should allow individual settings.
  1930. //
  1931. // ASSERT( ( BOOL )uc.fInheritMaxSessionTime == ( BOOL )uc.fInheritMaxDisconnectionTime );
  1932. // ASSERT( ( BOOL )uc.fInheritMaxSessionTime == ( BOOL )uc.fInheritMaxIdleTime );
  1933. DBGMSG( L"uc.fInheritMaxSessionTime %d\n" , uc.fInheritMaxSessionTime );
  1934. DBGMSG( L"uc.fInheritMaxDisconnectionTime %d\n" , uc.fInheritMaxDisconnectionTime );
  1935. DBGMSG( L"uc.fInheritMaxIdleTime %d\n" , uc.fInheritMaxIdleTime );
  1936. SendMessage( GetDlgItem( hwnd , IDC_CHECK_INHERITTIMEOUT_PS ) , BM_SETCHECK , ( WPARAM )( BOOL )!uc.fInheritMaxSessionTime , 0 );
  1937. SetTimeoutControls(hwnd);
  1938. SendMessage( GetDlgItem( hwnd , IDC_CHECK_TIMEOUTS_INHERITBKCON_PS ) , BM_SETCHECK , ( WPARAM )!uc.fInheritResetBroken , 0 );
  1939. if( uc.fResetBroken ) //BST_CHECKED : BST_UNCHECKED
  1940. {
  1941. CheckDlgButton( hwnd , IDC_RADIO_TIMEOUTS_RESET_PS , BST_CHECKED );
  1942. m_wOldAction = IDC_RADIO_TIMEOUTS_RESET_PS;
  1943. }
  1944. else
  1945. {
  1946. CheckDlgButton( hwnd , IDC_RADIO_TIMEOUTS_DISCON_PS , BST_CHECKED );
  1947. m_wOldAction = IDC_RADIO_TIMEOUTS_DISCON_PS;
  1948. }
  1949. /*
  1950. if( uc.fReconnectSame )
  1951. {
  1952. CheckDlgButton( hwnd , IDC_RADIO_TIMEOUTS_PREVCLNT_PS , BST_CHECKED );
  1953. m_wOldCon = IDC_RADIO_TIMEOUTS_PREVCLNT_PS;
  1954. }
  1955. else
  1956. {
  1957. CheckDlgButton( hwnd , IDC_RADIO_TIMEOUTS_ANYCLIENT_PS , BST_CHECKED );
  1958. m_wOldCon = IDC_RADIO_TIMEOUTS_ANYCLIENT_PS;
  1959. }
  1960. */
  1961. SetBkResetControls(hwnd);
  1962. SendMessage( GetDlgItem( hwnd , IDC_CHECK_TIMEOUTS_INHERITRECON_PS ) , BM_SETCHECK , ( WPARAM )!uc.fInheritReconnectSame , 0 );
  1963. //SetReconControls( hwnd , !uc.fInheritReconnectSame );
  1964. LoadAbbreviates( );
  1965. ICfgComp *pCfgcomp = NULL;
  1966. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) != 0 )
  1967. {
  1968. BOOL bReadOnly = FALSE;
  1969. if( SUCCEEDED( pCfgcomp->IsSessionReadOnly( &bReadOnly ) ) )
  1970. {
  1971. if( bReadOnly )
  1972. {
  1973. // disable the remaining controls
  1974. int rgID[] = {
  1975. IDC_COMBO_TIMEOUTS_CON_PS ,
  1976. IDC_COMBO_TIMEOUTS_DISCON_PS ,
  1977. IDC_COMBO_TIMEOUTS_IDLE_PS ,
  1978. IDC_RADIO_TIMEOUTS_DISCON_PS ,
  1979. IDC_RADIO_TIMEOUTS_RESET_PS ,
  1980. IDC_RADIO_TIMEOUTS_ANYCLIENT_PS ,
  1981. IDC_RADIO_TIMEOUTS_PREVCLNT_PS ,
  1982. IDC_CHECK_INHERITTIMEOUT_PS,
  1983. IDC_CHECK_TIMEOUTS_INHERITBKCON_PS,
  1984. IDC_CHECK_TIMEOUTS_INHERITRECON_PS,
  1985. -1
  1986. };
  1987. EnableGroup( hwnd , &rgID[ 0 ] , FALSE );
  1988. }
  1989. }
  1990. if( !bReadOnly )
  1991. {
  1992. ULONG mask = 0;
  1993. if( SUCCEEDED( pCfgcomp->GetCaps( m_pParent->m_pResNode->GetTypeName( ) , &mask ) ) )
  1994. {
  1995. // citrix only flag
  1996. m_bPrevClient = mask & WDC_RECONNECT_PREVCLIENT;
  1997. if( !m_bPrevClient )
  1998. {
  1999. EnableWindow( GetDlgItem( hwnd , IDC_CHECK_TIMEOUTS_INHERITRECON_PS ) , FALSE );
  2000. }
  2001. SetReconControls(hwnd);
  2002. }
  2003. }
  2004. pCfgcomp->Release( );
  2005. }
  2006. if( uc.fReconnectSame )
  2007. {
  2008. CheckDlgButton( hwnd , IDC_RADIO_TIMEOUTS_PREVCLNT_PS , BST_CHECKED );
  2009. m_wOldCon = IDC_RADIO_TIMEOUTS_PREVCLNT_PS;
  2010. }
  2011. else
  2012. {
  2013. CheckDlgButton( hwnd , IDC_RADIO_TIMEOUTS_ANYCLIENT_PS , BST_CHECKED );
  2014. m_wOldCon = IDC_RADIO_TIMEOUTS_ANYCLIENT_PS;
  2015. }
  2016. m_bPersisted = TRUE;
  2017. return CDialogPropBase::OnInitDialog( hwnd , wp , lp );
  2018. }
  2019. //-----------------------------------------------------------------------------
  2020. // the next set of functions manage the enabling and disabling of the controls
  2021. //-----------------------------------------------------------------------------
  2022. void CTimeSetting::SetTimeoutControls(HWND hDlg)
  2023. {
  2024. POLICY_TS_MACHINE p;
  2025. RegGetMachinePolicy(&p);
  2026. BOOL bOverride =
  2027. (SendMessage(GetDlgItem(hDlg, IDC_CHECK_INHERITTIMEOUT_PS), BM_GETCHECK, 0, 0) == BST_CHECKED);
  2028. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_TIMEOUTS_CON_PS), (bOverride && !p.fPolicyMaxSessionTime));
  2029. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TIMCON), (bOverride && !p.fPolicyMaxSessionTime));
  2030. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_TIMEOUTS_DISCON_PS), (bOverride && !p.fPolicyMaxDisconnectionTime));
  2031. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TIMDISCON), (bOverride && !p.fPolicyMaxDisconnectionTime));
  2032. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_TIMEOUTS_IDLE_PS), (bOverride && !p.fPolicyMaxIdleTime));
  2033. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TIMIDLE), (bOverride && !p.fPolicyMaxIdleTime));
  2034. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_INHERITTIMEOUT_PS),
  2035. !(p.fPolicyMaxSessionTime && p.fPolicyMaxDisconnectionTime && p.fPolicyMaxIdleTime));
  2036. }
  2037. void CTimeSetting::SetBkResetControls(HWND hDlg)
  2038. {
  2039. POLICY_TS_MACHINE p;
  2040. RegGetMachinePolicy(&p);
  2041. BOOL bOverride =
  2042. (SendMessage(GetDlgItem(hDlg, IDC_CHECK_TIMEOUTS_INHERITBKCON_PS), BM_GETCHECK, 0, 0) == BST_CHECKED);
  2043. EnableWindow(GetDlgItem(hDlg, IDC_RADIO_TIMEOUTS_DISCON_PS), bOverride && !p.fPolicyResetBroken);
  2044. EnableWindow(GetDlgItem(hDlg, IDC_RADIO_TIMEOUTS_RESET_PS), bOverride && !p.fPolicyResetBroken);
  2045. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_TIMEOUTS_INHERITBKCON_PS), !p.fPolicyResetBroken);
  2046. }
  2047. void CTimeSetting::SetReconControls(HWND hDlg)
  2048. {
  2049. POLICY_TS_MACHINE p;
  2050. RegGetMachinePolicy(&p);
  2051. BOOL bOverride =
  2052. (SendMessage(GetDlgItem(hDlg, IDC_CHECK_TIMEOUTS_INHERITRECON_PS), BM_GETCHECK, 0, 0) == BST_CHECKED);
  2053. if( !m_bPrevClient )
  2054. {
  2055. EnableWindow(GetDlgItem(hDlg, IDC_RADIO_TIMEOUTS_ANYCLIENT_PS), FALSE);
  2056. EnableWindow(GetDlgItem(hDlg, IDC_RADIO_TIMEOUTS_PREVCLNT_PS), FALSE);
  2057. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_TIMEOUTS_INHERITRECON_PS), FALSE);
  2058. }
  2059. else
  2060. {
  2061. EnableWindow(GetDlgItem(hDlg, IDC_RADIO_TIMEOUTS_ANYCLIENT_PS), bOverride && !p.fPolicyReconnectSame);
  2062. EnableWindow(GetDlgItem(hDlg, IDC_RADIO_TIMEOUTS_PREVCLNT_PS), bOverride && !p.fPolicyReconnectSame);
  2063. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_TIMEOUTS_INHERITRECON_PS), !p.fPolicyReconnectSame);
  2064. }
  2065. }
  2066. //-----------------------------------------------------------------------------
  2067. INT_PTR CALLBACK CTimeSetting::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  2068. {
  2069. CTimeSetting *pDlg;
  2070. if( msg == WM_INITDIALOG )
  2071. {
  2072. CTimeSetting *pDlg = ( CTimeSetting * )( ( PROPSHEETPAGE *)lp )->lParam ;
  2073. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  2074. if( !IsBadReadPtr( pDlg , sizeof( CTimeSetting ) ) )
  2075. {
  2076. pDlg->OnInitDialog( hwnd , wp , lp );
  2077. }
  2078. return 0;
  2079. }
  2080. else
  2081. {
  2082. pDlg = ( CTimeSetting * )GetWindowLongPtr( hwnd , DWLP_USER );
  2083. if( IsBadReadPtr( pDlg , sizeof( CTimeSetting ) ) )
  2084. {
  2085. return FALSE;
  2086. }
  2087. }
  2088. switch( msg )
  2089. {
  2090. case WM_NCDESTROY:
  2091. pDlg->OnDestroy( );
  2092. break;
  2093. case WM_COMMAND:
  2094. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  2095. break;
  2096. case WM_CONTEXTMENU:
  2097. {
  2098. POINT pt;
  2099. pt.x = LOWORD( lp );
  2100. pt.y = HIWORD( lp );
  2101. pDlg->OnContextMenu( ( HWND )wp , pt );
  2102. }
  2103. break;
  2104. case WM_HELP:
  2105. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  2106. break;
  2107. case WM_NOTIFY:
  2108. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  2109. }
  2110. return 0;
  2111. }
  2112. //-----------------------------------------------------------------------------
  2113. BOOL CTimeSetting::GetPropertySheetPage( PROPSHEETPAGE& psp )
  2114. {
  2115. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  2116. psp.dwSize = sizeof( PROPSHEETPAGE );
  2117. psp.dwFlags = PSP_DEFAULT;
  2118. psp.hInstance = _Module.GetResourceInstance( );
  2119. psp.pszTemplate = MAKEINTRESOURCE( IDD_TIMEOUTS_PS );
  2120. psp.lParam = ( LPARAM )this;
  2121. psp.pfnDlgProc = CTimeSetting::DlgProc;
  2122. return TRUE;
  2123. }
  2124. //-----------------------------------------------------------------------------
  2125. BOOL CTimeSetting::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  2126. {
  2127. if( wNotifyCode == BN_CLICKED )
  2128. {
  2129. if( wID == IDC_CHECK_INHERITTIMEOUT_PS )
  2130. {
  2131. SetTimeoutControls(GetParent(hwndCtrl));
  2132. m_bPersisted = FALSE;
  2133. }
  2134. else if( wID == IDC_CHECK_TIMEOUTS_INHERITBKCON_PS )
  2135. {
  2136. SetBkResetControls(GetParent(hwndCtrl));
  2137. m_bPersisted = FALSE;
  2138. }
  2139. else if( wID == IDC_CHECK_TIMEOUTS_INHERITRECON_PS )
  2140. {
  2141. SetReconControls(GetParent(hwndCtrl));
  2142. m_bPersisted = FALSE;
  2143. }
  2144. else if( wID == IDC_RADIO_TIMEOUTS_DISCON_PS || wID == IDC_RADIO_TIMEOUTS_RESET_PS )
  2145. {
  2146. if( wID != m_wOldAction )
  2147. {
  2148. m_wOldAction = wID;
  2149. m_bPersisted = FALSE;
  2150. }
  2151. }
  2152. else if( wID == IDC_RADIO_TIMEOUTS_ANYCLIENT_PS || wID == IDC_RADIO_TIMEOUTS_PREVCLNT_PS )
  2153. {
  2154. if( wID != m_wOldCon )
  2155. {
  2156. m_wOldCon = wID;
  2157. m_bPersisted = FALSE;
  2158. }
  2159. }
  2160. }
  2161. else if( wNotifyCode == ALN_APPLY )
  2162. {
  2163. SendMessage( GetParent( hwndCtrl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  2164. return FALSE;
  2165. }
  2166. else
  2167. {
  2168. CTimeOutDlg::OnCommand( wNotifyCode , wID , hwndCtrl , &m_bPersisted );
  2169. }
  2170. if( !m_bPersisted )
  2171. {
  2172. SendMessage( GetParent( GetParent( hwndCtrl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtrl ) , 0 );
  2173. }
  2174. return FALSE;
  2175. }
  2176. //-----------------------------------------------------------------------------
  2177. int CTimeSetting::GetCBXSTATEindex( HWND hCombo )
  2178. {
  2179. int idx = -1;
  2180. switch( GetDlgCtrlID( hCombo ) )
  2181. {
  2182. case IDC_COMBO_TIMEOUTS_CON_PS:
  2183. idx = 0;
  2184. break;
  2185. case IDC_COMBO_TIMEOUTS_DISCON_PS:
  2186. idx = 1;
  2187. break;
  2188. case IDC_COMBO_TIMEOUTS_IDLE_PS:
  2189. idx = 2;
  2190. break;
  2191. }
  2192. return idx;
  2193. }
  2194. //-------------------------------------------------------------------------------
  2195. // PersistSettings
  2196. //-------------------------------------------------------------------------------
  2197. BOOL CTimeSetting::PersistSettings( HWND hDlg )
  2198. {
  2199. if( m_pParent == NULL )
  2200. {
  2201. return FALSE;
  2202. }
  2203. USERCONFIG uc;
  2204. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  2205. {
  2206. return FALSE;
  2207. }
  2208. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_INHERITTIMEOUT_PS ) , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED )
  2209. {
  2210. uc.fInheritMaxSessionTime = 1;
  2211. uc.fInheritMaxDisconnectionTime = 1;
  2212. uc.fInheritMaxIdleTime = 1;
  2213. // reset timeout values to no timeout
  2214. uc.MaxConnectionTime = 0;
  2215. uc.MaxDisconnectionTime = 0;
  2216. uc.MaxIdleTime = 0;
  2217. }
  2218. else
  2219. {
  2220. uc.fInheritMaxSessionTime = 0;
  2221. uc.fInheritMaxDisconnectionTime = 0;
  2222. uc.fInheritMaxIdleTime = 0;
  2223. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_TIMEOUTS_CON_PS ) , &uc.MaxConnectionTime ) )
  2224. {
  2225. return FALSE;
  2226. }
  2227. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_TIMEOUTS_DISCON_PS ) , &uc.MaxDisconnectionTime ) )
  2228. {
  2229. return FALSE;
  2230. }
  2231. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_TIMEOUTS_IDLE_PS ) , &uc.MaxIdleTime ) )
  2232. {
  2233. return FALSE;
  2234. }
  2235. }
  2236. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_TIMEOUTS_INHERITBKCON_PS ) , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED )
  2237. {
  2238. uc.fInheritResetBroken = 1;
  2239. }
  2240. else
  2241. {
  2242. uc.fInheritResetBroken = 0;
  2243. uc.fResetBroken = SendMessage( GetDlgItem( hDlg , IDC_RADIO_TIMEOUTS_RESET_PS ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  2244. }
  2245. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_TIMEOUTS_INHERITRECON_PS ) , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED )
  2246. {
  2247. uc.fInheritReconnectSame = 1;
  2248. }
  2249. else
  2250. {
  2251. uc.fInheritReconnectSame = 0;
  2252. uc.fReconnectSame = ( ULONG )SendMessage( GetDlgItem( hDlg , IDC_RADIO_TIMEOUTS_PREVCLNT_PS ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  2253. }
  2254. DWORD dwStatus;
  2255. if( FAILED( m_pParent->SetUserConfig( uc , &dwStatus ) ) )
  2256. {
  2257. ReportStatusError( hDlg , dwStatus );
  2258. return FALSE;
  2259. }
  2260. ICfgComp *pCfgcomp = NULL;
  2261. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) > 0 )
  2262. {
  2263. VERIFY_S( S_OK , pCfgcomp->ForceUpdate( ) );
  2264. VERIFY_S( S_OK , pCfgcomp->Refresh( ) );
  2265. // global flag can only be set to true
  2266. m_pParent->m_bPropertiesChange = TRUE;
  2267. pCfgcomp->Release( );
  2268. }
  2269. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  2270. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  2271. return TRUE;
  2272. }
  2273. //-------------------------------------------------------------------------------
  2274. // Making sure the user has entered valid info
  2275. //-------------------------------------------------------------------------------
  2276. BOOL CTimeSetting::IsValidSettings( HWND hDlg )
  2277. {
  2278. if( m_pParent == NULL )
  2279. {
  2280. return FALSE;
  2281. }
  2282. USERCONFIG uc;
  2283. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  2284. {
  2285. return FALSE;
  2286. }
  2287. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_INHERITTIMEOUT_PS ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED )
  2288. {
  2289. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_TIMEOUTS_CON_PS ) , &uc.MaxConnectionTime ) )
  2290. {
  2291. return FALSE;
  2292. }
  2293. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_TIMEOUTS_DISCON_PS ) , &uc.MaxDisconnectionTime ) )
  2294. {
  2295. return FALSE;
  2296. }
  2297. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_TIMEOUTS_IDLE_PS ) , &uc.MaxIdleTime ) )
  2298. {
  2299. return FALSE;
  2300. }
  2301. }
  2302. return TRUE;
  2303. }
  2304. //-----------------------------------------------------------------------------
  2305. BOOL CTimeSetting::OnDestroy( )
  2306. {
  2307. m_pParent->Release( );
  2308. ReleaseAbbreviates( );
  2309. return CDialogPropBase::OnDestroy( );
  2310. }
  2311. //*****************************************************************************
  2312. // Environment dialog
  2313. CEnviro::CEnviro( CPropsheet *pSheet )
  2314. {
  2315. m_pParent = pSheet;
  2316. }
  2317. //-----------------------------------------------------------------------------
  2318. BOOL CEnviro::OnInitDialog( HWND hwnd , WPARAM wp , LPARAM lp )
  2319. {
  2320. if( m_pParent == NULL )
  2321. {
  2322. ODS( L"CEnviro::OnInitDialog - PropertySheet: Parent object is lost!!!\n" );
  2323. return FALSE;
  2324. }
  2325. m_pParent->AddRef( );
  2326. USERCONFIG uc;
  2327. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  2328. {
  2329. ODS( L"CEnviro::OnInitDialog - PropertySheet: Failed to obtain USERCONFIG\n" );
  2330. return FALSE;
  2331. }
  2332. SendMessage( GetDlgItem( hwnd , IDC_EDIT_ENVIRO_CMDLINE ) , EM_SETLIMITTEXT , ( WPARAM )INITIALPROGRAM_LENGTH , 0 );
  2333. SendMessage( GetDlgItem( hwnd , IDC_EDIT_ENVIRO_WD ) , EM_SETLIMITTEXT , ( WPARAM )DIRECTORY_LENGTH , 0 );
  2334. if(uc.fInheritInitialProgram)
  2335. {
  2336. SendMessage( GetDlgItem( hwnd , IDC_CHECK_ENVIRO_INHERIT ) , BM_SETCHECK , ( WPARAM )BST_UNCHECKED , 0 );
  2337. }
  2338. else
  2339. {
  2340. SendMessage( GetDlgItem( hwnd , IDC_CHECK_ENVIRO_INHERIT ) , BM_SETCHECK , ( WPARAM )BST_CHECKED, 0 );
  2341. }
  2342. if(uc.fInheritInitialProgram)
  2343. {
  2344. SetControls( hwnd , FALSE );
  2345. }
  2346. else
  2347. {
  2348. SetWindowText( GetDlgItem( hwnd , IDC_EDIT_ENVIRO_CMDLINE ) , ( LPCTSTR )uc.InitialProgram );
  2349. SetWindowText( GetDlgItem( hwnd , IDC_EDIT_ENVIRO_WD ) , ( LPCTSTR )uc.WorkDirectory );
  2350. }
  2351. // SendMessage( GetDlgItem( hwnd , IDC_CHECK_ENVIRO_DISABLEWALL ) , BM_SETCHECK , ( WPARAM )uc.fWallPaperDisabled , 0 );
  2352. ICfgComp *pCfgcomp = NULL;
  2353. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) != 0 )
  2354. {
  2355. BOOL bReadOnly;
  2356. if( SUCCEEDED( pCfgcomp->IsSessionReadOnly( &bReadOnly ) ) )
  2357. {
  2358. if( bReadOnly )
  2359. {
  2360. // make edit controls read-only
  2361. SendMessage( GetDlgItem( hwnd , IDC_EDIT_ENVIRO_CMDLINE ) , EM_SETREADONLY , ( WPARAM )TRUE , 0 );
  2362. SendMessage( GetDlgItem( hwnd , IDC_EDIT_ENVIRO_WD ) , EM_SETREADONLY , ( WPARAM )TRUE , 0 );
  2363. // disable the remaining controls
  2364. int rgID[] = {
  2365. IDC_CHECK_ENVIRO_INHERIT ,
  2366. // IDC_CHECK_ENVIRO_DISABLEWALL,
  2367. -1
  2368. };
  2369. EnableGroup( hwnd , &rgID[ 0 ] , FALSE );
  2370. }
  2371. }
  2372. pCfgcomp->Release( );
  2373. }
  2374. POLICY_TS_MACHINE p;
  2375. RegGetMachinePolicy(&p);
  2376. if (p.fPolicyInitialProgram)
  2377. {
  2378. int rgID[] =
  2379. {
  2380. IDC_CHECK_ENVIRO_INHERIT,
  2381. IDC_EDIT_ENVIRO_CMDLINE,
  2382. IDC_EDIT_ENVIRO_WD, -1
  2383. };
  2384. EnableGroup(hwnd, &rgID[0], FALSE);
  2385. }
  2386. m_bPersisted = TRUE;
  2387. return CDialogPropBase::OnInitDialog( hwnd , wp , lp );
  2388. }
  2389. //-----------------------------------------------------------------------------
  2390. INT_PTR CALLBACK CEnviro::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  2391. {
  2392. CEnviro *pDlg;
  2393. if( msg == WM_INITDIALOG )
  2394. {
  2395. CEnviro *pDlg = ( CEnviro * )( ( PROPSHEETPAGE *)lp )->lParam ;
  2396. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  2397. if( !IsBadReadPtr( pDlg , sizeof( CEnviro ) ) )
  2398. {
  2399. pDlg->OnInitDialog( hwnd , wp , lp );
  2400. }
  2401. return 0;
  2402. }
  2403. else
  2404. {
  2405. pDlg = ( CEnviro * )GetWindowLongPtr( hwnd , DWLP_USER );
  2406. if( IsBadReadPtr( pDlg , sizeof( CEnviro ) ) )
  2407. {
  2408. return 0;
  2409. }
  2410. }
  2411. switch( msg )
  2412. {
  2413. case WM_NCDESTROY:
  2414. pDlg->OnDestroy( );
  2415. break;
  2416. case WM_COMMAND:
  2417. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  2418. break;
  2419. case WM_CONTEXTMENU:
  2420. {
  2421. POINT pt;
  2422. pt.x = LOWORD( lp );
  2423. pt.y = HIWORD( lp );
  2424. pDlg->OnContextMenu( ( HWND )wp , pt );
  2425. }
  2426. break;
  2427. case WM_HELP:
  2428. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  2429. break;
  2430. case WM_NOTIFY:
  2431. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  2432. }
  2433. return 0;
  2434. }
  2435. //-----------------------------------------------------------------------------
  2436. BOOL CEnviro::GetPropertySheetPage( PROPSHEETPAGE& psp )
  2437. {
  2438. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  2439. psp.dwSize = sizeof( PROPSHEETPAGE );
  2440. psp.dwFlags = PSP_DEFAULT;
  2441. psp.hInstance = _Module.GetResourceInstance( );
  2442. psp.pszTemplate = MAKEINTRESOURCE( IDD_ENVIRONMENT );
  2443. psp.lParam = ( LPARAM )this;
  2444. psp.pfnDlgProc = CEnviro::DlgProc;
  2445. return TRUE;
  2446. }
  2447. //-----------------------------------------------------------------------------
  2448. BOOL CEnviro::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  2449. {
  2450. if( wNotifyCode == BN_CLICKED )
  2451. {
  2452. if( wID == IDC_CHECK_ENVIRO_INHERIT )
  2453. {
  2454. SetControls( GetParent( hwndCtrl ) , SendMessage( hwndCtrl , BM_GETCHECK , 0 , 0 ) == BST_CHECKED );
  2455. }
  2456. m_bPersisted = FALSE;
  2457. }
  2458. else if( wNotifyCode == EN_CHANGE )
  2459. {
  2460. m_bPersisted = FALSE;
  2461. }
  2462. else if( wNotifyCode == ALN_APPLY )
  2463. {
  2464. SendMessage( GetParent( hwndCtrl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  2465. return FALSE;
  2466. }
  2467. if( !m_bPersisted )
  2468. {
  2469. SendMessage( GetParent( GetParent( hwndCtrl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtrl ) , 0 );
  2470. }
  2471. return FALSE;
  2472. }
  2473. //-----------------------------------------------------------------------------
  2474. void CEnviro::SetControls( HWND hDlg , BOOL bEnable )
  2475. {
  2476. int rgID[] = { IDC_EDIT_ENVIRO_CMDLINE , IDC_STATIC_ENCL , IDC_EDIT_ENVIRO_WD , IDC_STATIC_WD ,-1 };
  2477. EnableGroup( hDlg , &rgID[ 0 ] , bEnable );
  2478. }
  2479. //-----------------------------------------------------------------------------
  2480. BOOL CEnviro::PersistSettings( HWND hDlg )
  2481. {
  2482. if( m_pParent == NULL )
  2483. {
  2484. return FALSE;
  2485. }
  2486. USERCONFIG uc;
  2487. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  2488. {
  2489. return FALSE;
  2490. }
  2491. uc.fInheritInitialProgram = (( ULONG )SendMessage( GetDlgItem( hDlg , IDC_CHECK_ENVIRO_INHERIT ) , BM_GETCHECK , 0 , 0 )) == BST_UNCHECKED;
  2492. if( !uc.fInheritInitialProgram )
  2493. {
  2494. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_ENVIRO_CMDLINE ) , uc.InitialProgram , INITIALPROGRAM_LENGTH + 1);
  2495. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_ENVIRO_WD ) , uc.WorkDirectory , DIRECTORY_LENGTH + 1 );
  2496. }
  2497. else
  2498. {
  2499. ZeroMemory( ( PVOID )uc.InitialProgram , sizeof( uc.InitialProgram ) );
  2500. ZeroMemory( ( PVOID )uc.WorkDirectory , sizeof( uc.WorkDirectory ) );
  2501. }
  2502. // uc.fWallPaperDisabled = ( ULONG )SendMessage( GetDlgItem( hDlg , IDC_CHECK_ENVIRO_DISABLEWALL ) , BM_GETCHECK , 0 , 0 );
  2503. DWORD dwStatus;
  2504. if( FAILED( m_pParent->SetUserConfig( uc , &dwStatus ) ) )
  2505. {
  2506. ReportStatusError( hDlg , dwStatus );
  2507. return FALSE;
  2508. }
  2509. ICfgComp *pCfgcomp = NULL;
  2510. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) > 0 )
  2511. {
  2512. VERIFY_S( S_OK , pCfgcomp->ForceUpdate( ) );
  2513. VERIFY_S( S_OK , pCfgcomp->Refresh( ) );
  2514. // global flag can only be set to true
  2515. m_pParent->m_bPropertiesChange = TRUE;
  2516. pCfgcomp->Release( );
  2517. }
  2518. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  2519. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  2520. return TRUE;
  2521. }
  2522. //-----------------------------------------------------------------------------
  2523. BOOL CEnviro::OnDestroy( )
  2524. {
  2525. m_pParent->Release( );
  2526. return CDialogPropBase::OnDestroy( );
  2527. }
  2528. //*****************************************************************************
  2529. // Shadow dialog
  2530. CRemote::CRemote( CPropsheet *pSheet )
  2531. {
  2532. m_pParent = pSheet;
  2533. m_wOldRadioID = ( WORD )-1;
  2534. m_wOldSel = ( WORD )-1;
  2535. }
  2536. //-----------------------------------------------------------------------------
  2537. BOOL CRemote::OnInitDialog( HWND hwnd , WPARAM wp , LPARAM lp )
  2538. {
  2539. if( m_pParent == NULL )
  2540. {
  2541. ODS( L"CRemote::OnInitDialog - PropertySheet: Parent object lost!!\n" );
  2542. return FALSE;
  2543. }
  2544. m_pParent->AddRef( );
  2545. USERCONFIG uc;
  2546. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  2547. {
  2548. ODS( L"CRemote::OnInitDialog - PropertySheet: GetCurrentUserConfig failed!!\n" );
  2549. return FALSE;
  2550. }
  2551. if( uc.fInheritShadow || uc.Shadow == Shadow_Disable )
  2552. {
  2553. // setup some default values
  2554. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2555. SendMessage( GetDlgItem( hwnd , IDC_RADIO_WATCH ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2556. m_wOldSel = IDC_RADIO_WATCH;
  2557. if( uc.fInheritShadow )
  2558. {
  2559. SendMessage( GetDlgItem( hwnd , IDC_RADIO_REMOTE_INHERIT ) , BM_SETCHECK , ( WPARAM )uc.fInheritShadow , 0 );
  2560. }
  2561. else
  2562. {
  2563. SendMessage( GetDlgItem( hwnd , IDC_RADIO_NOREMOTE ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2564. }
  2565. m_wOldRadioID = ( WORD )( uc.fInheritShadow ? IDC_RADIO_REMOTE_INHERIT : IDC_RADIO_NOREMOTE );
  2566. SetControls( hwnd , FALSE );
  2567. }
  2568. else
  2569. {
  2570. // Controls are initially enabled, set current status
  2571. SendMessage( GetDlgItem( hwnd , IDC_RADIO_ENABLE_REMOTE ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2572. m_wOldRadioID = IDC_RADIO_ENABLE_REMOTE;
  2573. switch( uc.Shadow )
  2574. {
  2575. case Shadow_EnableInputNotify:
  2576. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2577. SendMessage( GetDlgItem( hwnd , IDC_RADIO_CONTROL ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2578. break;
  2579. case Shadow_EnableInputNoNotify:
  2580. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )FALSE , 0 );
  2581. SendMessage( GetDlgItem( hwnd , IDC_RADIO_CONTROL ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2582. break;
  2583. case Shadow_EnableNoInputNotify:
  2584. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2585. SendMessage( GetDlgItem( hwnd , IDC_RADIO_WATCH ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2586. break;
  2587. case Shadow_EnableNoInputNoNotify:
  2588. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )FALSE , 0 );
  2589. SendMessage( GetDlgItem( hwnd , IDC_RADIO_WATCH ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  2590. break;
  2591. }
  2592. if( IsDlgButtonChecked( hwnd , IDC_RADIO_WATCH ) == BST_CHECKED )
  2593. {
  2594. m_wOldSel = IDC_RADIO_WATCH;
  2595. }
  2596. else
  2597. {
  2598. m_wOldSel = IDC_RADIO_CONTROL;
  2599. }
  2600. }
  2601. ICfgComp *pCfgcomp = NULL;
  2602. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) != 0 )
  2603. {
  2604. BOOL bReadOnly;
  2605. if( SUCCEEDED( pCfgcomp->IsSessionReadOnly( &bReadOnly ) ) )
  2606. {
  2607. if( bReadOnly )
  2608. {
  2609. // disable the remaining controls
  2610. int rgID[] = {
  2611. IDC_RADIO_ENABLE_REMOTE ,
  2612. IDC_RADIO_NOREMOTE,
  2613. IDC_RADIO_CONTROL,
  2614. IDC_RADIO_REMOTE_INHERIT,
  2615. IDC_RADIO_WATCH,
  2616. IDC_CHECK_NOTIFY,
  2617. -1
  2618. };
  2619. EnableGroup( hwnd , &rgID[ 0 ] , FALSE );
  2620. }
  2621. }
  2622. pCfgcomp->Release( );
  2623. }
  2624. //Disable all the controls if there is a group policy set
  2625. POLICY_TS_MACHINE p;
  2626. RegGetMachinePolicy(&p);
  2627. if (p.fPolicyShadow)
  2628. {
  2629. int rgID[] =
  2630. {
  2631. IDC_RADIO_ENABLE_REMOTE ,
  2632. IDC_RADIO_NOREMOTE,
  2633. IDC_RADIO_CONTROL,
  2634. IDC_RADIO_REMOTE_INHERIT,
  2635. IDC_RADIO_WATCH,
  2636. IDC_CHECK_NOTIFY,
  2637. -1
  2638. };
  2639. EnableGroup( hwnd , &rgID[ 0 ] , FALSE );
  2640. }
  2641. m_bPersisted = TRUE;
  2642. return CDialogPropBase::OnInitDialog( hwnd , wp , lp );
  2643. }
  2644. //-----------------------------------------------------------------------------
  2645. void CRemote::SetControls( HWND hDlg , BOOL bEnable )
  2646. {
  2647. int rgID[] = { IDC_RADIO_WATCH , IDC_RADIO_CONTROL , IDC_CHECK_NOTIFY , IDC_STATIC_LEVELOFCTRL , -1 };
  2648. EnableGroup( hDlg , &rgID[ 0 ] , bEnable );
  2649. }
  2650. //-----------------------------------------------------------------------------
  2651. INT_PTR CALLBACK CRemote::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  2652. {
  2653. CRemote *pDlg;
  2654. if( msg == WM_INITDIALOG )
  2655. {
  2656. CRemote *pDlg = ( CRemote * )( ( PROPSHEETPAGE *)lp )->lParam ;
  2657. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  2658. if( !IsBadReadPtr( pDlg , sizeof( CRemote ) ) )
  2659. {
  2660. pDlg->OnInitDialog( hwnd , wp , lp );
  2661. }
  2662. return 0;
  2663. }
  2664. else
  2665. {
  2666. pDlg = ( CRemote * )GetWindowLongPtr( hwnd , DWLP_USER );
  2667. if( IsBadReadPtr( pDlg , sizeof( CRemote ) ) )
  2668. {
  2669. return 0;
  2670. }
  2671. }
  2672. switch( msg )
  2673. {
  2674. case WM_NCDESTROY:
  2675. pDlg->OnDestroy( );
  2676. break;
  2677. case WM_COMMAND:
  2678. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  2679. break;
  2680. case WM_CONTEXTMENU:
  2681. {
  2682. POINT pt;
  2683. pt.x = LOWORD( lp );
  2684. pt.y = HIWORD( lp );
  2685. pDlg->OnContextMenu( ( HWND )wp , pt );
  2686. }
  2687. break;
  2688. case WM_HELP:
  2689. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  2690. break;
  2691. case WM_NOTIFY:
  2692. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  2693. }
  2694. return 0;
  2695. }
  2696. //-----------------------------------------------------------------------------
  2697. BOOL CRemote::GetPropertySheetPage( PROPSHEETPAGE& psp )
  2698. {
  2699. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  2700. psp.dwSize = sizeof( PROPSHEETPAGE );
  2701. psp.dwFlags = PSP_DEFAULT;
  2702. psp.hInstance = _Module.GetResourceInstance( );
  2703. psp.pszTemplate = MAKEINTRESOURCE( IDD_PAGE_SHADOW );
  2704. psp.lParam = ( LPARAM )this;
  2705. psp.pfnDlgProc = CRemote::DlgProc;
  2706. return TRUE;
  2707. }
  2708. //-----------------------------------------------------------------------------
  2709. BOOL CRemote::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  2710. {
  2711. if( wNotifyCode == BN_CLICKED )
  2712. {
  2713. if( wID == IDC_CHECK_NOTIFY )
  2714. {
  2715. m_bPersisted = FALSE;
  2716. }
  2717. else if( wID == IDC_RADIO_REMOTE_INHERIT || wID == IDC_RADIO_NOREMOTE || wID == IDC_RADIO_ENABLE_REMOTE )
  2718. {
  2719. if( m_wOldRadioID != wID )
  2720. {
  2721. if( wID == IDC_RADIO_REMOTE_INHERIT || wID == IDC_RADIO_NOREMOTE )
  2722. {
  2723. SetControls( GetParent( hwndCtrl ) , FALSE );
  2724. }
  2725. else if( wID == IDC_RADIO_ENABLE_REMOTE )
  2726. {
  2727. SetControls( GetParent( hwndCtrl ) , TRUE );
  2728. }
  2729. m_wOldRadioID = wID;
  2730. m_bPersisted = FALSE;
  2731. }
  2732. }
  2733. else if( wID == IDC_RADIO_CONTROL || wID == IDC_RADIO_WATCH )
  2734. {
  2735. if( wID != m_wOldSel )
  2736. {
  2737. m_wOldSel = wID;
  2738. m_bPersisted = FALSE;
  2739. }
  2740. }
  2741. }
  2742. else if( wNotifyCode == ALN_APPLY )
  2743. {
  2744. SendMessage( GetParent( hwndCtrl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  2745. return FALSE;
  2746. }
  2747. if( !m_bPersisted )
  2748. {
  2749. SendMessage( GetParent( GetParent( hwndCtrl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtrl ) , 0 );
  2750. }
  2751. return FALSE;
  2752. }
  2753. //-----------------------------------------------------------------------------
  2754. BOOL CRemote::OnDestroy( )
  2755. {
  2756. m_pParent->Release( );
  2757. return CDialogPropBase::OnDestroy( );
  2758. }
  2759. //-----------------------------------------------------------------------------
  2760. // The nesting may appear scary but its has a nice logic flow to a weird
  2761. // datatype called shadow
  2762. //-----------------------------------------------------------------------------
  2763. BOOL CRemote::PersistSettings( HWND hDlg )
  2764. {
  2765. if( m_pParent != NULL )
  2766. {
  2767. USERCONFIG uc;
  2768. m_pParent->GetCurrentUserConfig( uc, TRUE );
  2769. if( SendMessage( GetDlgItem( hDlg , IDC_RADIO_REMOTE_INHERIT ) , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED )
  2770. {
  2771. uc.fInheritShadow = FALSE;
  2772. if( SendMessage( GetDlgItem( hDlg , IDC_RADIO_NOREMOTE ) , BM_GETCHECK , 0 , 0 ) == BST_UNCHECKED )
  2773. {
  2774. BOOL bCheckNotify = ( BOOL )SendMessage( GetDlgItem( hDlg , IDC_CHECK_NOTIFY ) , BM_GETCHECK , 0 , 0 );
  2775. BOOL bRadioControl = ( BOOL )SendMessage( GetDlgItem( hDlg , IDC_RADIO_CONTROL ) , BM_GETCHECK , 0 , 0 );
  2776. if( bCheckNotify )
  2777. {
  2778. if( bRadioControl )
  2779. {
  2780. uc.Shadow = Shadow_EnableInputNotify;
  2781. }
  2782. else
  2783. {
  2784. uc.Shadow = Shadow_EnableNoInputNotify;
  2785. }
  2786. }
  2787. else
  2788. {
  2789. if( bRadioControl )
  2790. {
  2791. uc.Shadow = Shadow_EnableInputNoNotify;
  2792. }
  2793. else
  2794. {
  2795. uc.Shadow = Shadow_EnableNoInputNoNotify;
  2796. }
  2797. }
  2798. }
  2799. else
  2800. {
  2801. uc.Shadow = Shadow_Disable;
  2802. }
  2803. }
  2804. else
  2805. {
  2806. uc.fInheritShadow = TRUE;
  2807. }
  2808. DWORD dwStatus;
  2809. if( FAILED( m_pParent->SetUserConfig( uc , &dwStatus ) ) )
  2810. {
  2811. ReportStatusError( hDlg , dwStatus );
  2812. return FALSE;
  2813. }
  2814. ICfgComp *pCfgcomp = NULL;
  2815. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) > 0 )
  2816. {
  2817. VERIFY_S( S_OK , pCfgcomp->ForceUpdate( ) );
  2818. VERIFY_S( S_OK , pCfgcomp->Refresh( ) );
  2819. // global flag can only be set to true
  2820. m_pParent->m_bPropertiesChange = TRUE;
  2821. pCfgcomp->Release( );
  2822. }
  2823. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  2824. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  2825. return TRUE;
  2826. }
  2827. return FALSE;
  2828. }
  2829. //*****************************************************************************
  2830. // Client settings dialog
  2831. CClient::CClient( CPropsheet *pSheet )
  2832. {
  2833. m_pParent = pSheet;
  2834. m_nColorDepth = TS_8BPP_SUPPORT;
  2835. }
  2836. //-----------------------------------------------------------------------------
  2837. BOOL CClient::OnInitDialog( HWND hDlg , WPARAM wp , LPARAM lp )
  2838. {
  2839. if( m_pParent == NULL )
  2840. {
  2841. ODS( L"CClient::OnInitDialog - PropertySheet: Parent object lost!!\n" );
  2842. return FALSE;
  2843. }
  2844. m_pParent->AddRef( );
  2845. USERCONFIG uc;
  2846. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  2847. {
  2848. ODS( L"CClient::OnInitDialog - PropertySheet: GetCurrentUserConfig failed!!\n" );
  2849. return FALSE;
  2850. }
  2851. // Obtain capabilities mask
  2852. ICfgComp *pCfgcomp = NULL;
  2853. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  2854. {
  2855. ODS( L"CClient::OnInitDialog GetServer failed\n" );
  2856. return FALSE;
  2857. }
  2858. SendMessage( GetDlgItem( hDlg , IDC_CHECK_CONCLIENT_INHERIT ) , BM_SETCHECK , ( WPARAM )uc.fInheritAutoClient , 0 );
  2859. SendMessage( GetDlgItem( hDlg , IDC_CHECK_CCDL_PS ) , BM_SETCHECK , ( WPARAM )uc.fAutoClientDrives , 0 );
  2860. SendMessage( GetDlgItem( hDlg , IDC_CHECK_CCPL_PS ) , BM_SETCHECK , ( WPARAM )uc.fAutoClientLpts , 0 );
  2861. SendMessage( GetDlgItem( hDlg , IDC_CHECK_DMCP_PS ) , BM_SETCHECK , ( WPARAM )uc.fForceClientLptDef , 0 );
  2862. TCHAR tchBuffer[80];
  2863. int nColorDepthIndex = 0;
  2864. LoadString( _Module.GetResourceInstance( ) , IDS_COLORDEPTH_24 , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) );
  2865. SendMessage( GetDlgItem( hDlg, IDC_COLORDEPTH_OVERRIDE ), CB_ADDSTRING , 0 , ( LPARAM )&tchBuffer[0] );
  2866. SendMessage( GetDlgItem( hDlg, IDC_COLORDEPTH_OVERRIDE ), CB_SETITEMDATA , nColorDepthIndex++ , TS_24BPP_SUPPORT );
  2867. LoadString( _Module.GetResourceInstance( ) , IDS_COLORDEPTH_16 , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) );
  2868. SendMessage( GetDlgItem( hDlg, IDC_COLORDEPTH_OVERRIDE ), CB_ADDSTRING , 0 , ( LPARAM )&tchBuffer[0] );
  2869. SendMessage( GetDlgItem( hDlg, IDC_COLORDEPTH_OVERRIDE ), CB_SETITEMDATA , nColorDepthIndex++ , TS_16BPP_SUPPORT );
  2870. LoadString( _Module.GetResourceInstance( ) , IDS_COLORDEPTH_15 , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) );
  2871. SendMessage( GetDlgItem( hDlg, IDC_COLORDEPTH_OVERRIDE ), CB_ADDSTRING , 0 , ( LPARAM )&tchBuffer[0] );
  2872. SendMessage( GetDlgItem( hDlg, IDC_COLORDEPTH_OVERRIDE ), CB_SETITEMDATA , nColorDepthIndex++ , TS_15BPP_SUPPORT );
  2873. LoadString( _Module.GetResourceInstance( ) , IDS_COLORDEPTH_8 , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) );
  2874. SendMessage( GetDlgItem( hDlg, IDC_COLORDEPTH_OVERRIDE ), CB_ADDSTRING , 0 , ( LPARAM )&tchBuffer[0] );
  2875. SendMessage( GetDlgItem( hDlg, IDC_COLORDEPTH_OVERRIDE ), CB_SETITEMDATA , nColorDepthIndex++ , TS_8BPP_SUPPORT );
  2876. if(uc.fInheritColorDepth)
  2877. SendMessage( GetDlgItem( hDlg , IDC_CHECK_COLORDEPTH_OVERRIDE ) , BM_SETCHECK , ( WPARAM )BST_UNCHECKED , 0 );
  2878. else
  2879. SendMessage( GetDlgItem( hDlg , IDC_CHECK_COLORDEPTH_OVERRIDE ) , BM_SETCHECK , ( WPARAM )BST_CHECKED, 0 );
  2880. if (uc.ColorDepth < TS_8BPP_SUPPORT)
  2881. m_nColorDepth = TS_8BPP_SUPPORT;
  2882. else if (uc.ColorDepth > TS_24BPP_SUPPORT)
  2883. m_nColorDepth = TS_24BPP_SUPPORT;
  2884. else
  2885. m_nColorDepth = (int)uc.ColorDepth;
  2886. //Mapping fields
  2887. ULONG mask = 0;
  2888. VERIFY_S(S_OK, pCfgcomp->GetCaps(m_pParent->m_pResNode->GetTypeName(), &mask));
  2889. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCDM_PS), mask & WDC_CLIENT_DRIVE_MAPPING);
  2890. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DWCPM_PS), mask & WDC_WIN_CLIENT_PRINTER_MAPPING);
  2891. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCLPM_PS), mask & WDC_CLIENT_LPT_PORT_MAPPING);
  2892. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCCPM_PS), mask & WDC_CLIENT_COM_PORT_MAPPING);
  2893. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCCM_PS), mask & WDC_CLIENT_CLIPBOARD_MAPPING);
  2894. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCAM_PS), mask & WDC_CLIENT_AUDIO_MAPPING);
  2895. if (!(mask & WDC_CLIENT_DRIVE_MAPPING))
  2896. SendMessage(GetDlgItem(hDlg, IDC_CHECK_DCDM_PS), BM_SETCHECK, (WPARAM)TRUE, 0);
  2897. else
  2898. SendMessage(GetDlgItem(hDlg, IDC_CHECK_DCDM_PS), BM_SETCHECK, (WPARAM)uc.fDisableCdm, 0);
  2899. if(!(mask & WDC_WIN_CLIENT_PRINTER_MAPPING))
  2900. SendMessage(GetDlgItem(hDlg, IDC_CHECK_DWCPM_PS), BM_SETCHECK, (WPARAM)TRUE, 0 );
  2901. else
  2902. SendMessage(GetDlgItem(hDlg, IDC_CHECK_DWCPM_PS), BM_SETCHECK, (WPARAM)uc.fDisableCpm, 0);
  2903. if(!(mask & WDC_CLIENT_LPT_PORT_MAPPING))
  2904. SendMessage(GetDlgItem(hDlg, IDC_CHECK_DCLPM_PS), BM_SETCHECK, (WPARAM)TRUE, 0);
  2905. else
  2906. SendMessage(GetDlgItem(hDlg, IDC_CHECK_DCLPM_PS), BM_SETCHECK, (WPARAM)uc.fDisableLPT, 0);
  2907. SendMessage( GetDlgItem( hDlg , IDC_CHECK_DCCPM_PS ) , BM_SETCHECK , ( WPARAM )uc.fDisableCcm , 0 );
  2908. SendMessage( GetDlgItem( hDlg , IDC_CHECK_DCCM_PS ) , BM_SETCHECK , ( WPARAM )uc.fDisableClip , 0 );
  2909. SendMessage( GetDlgItem( hDlg , IDC_CHECK_DCAM_PS ) , BM_SETCHECK , ( WPARAM )uc.fDisableCam , 0 );
  2910. DetermineFieldEnabling(hDlg);
  2911. SetColorDepthEntry(hDlg);
  2912. BOOL bReadOnly;
  2913. if (SUCCEEDED(pCfgcomp->IsSessionReadOnly(&bReadOnly)))
  2914. {
  2915. if(bReadOnly)
  2916. {
  2917. // disable the remaining controls
  2918. int rgID[] =
  2919. {
  2920. IDC_CHECK_DCDM_PS ,
  2921. IDC_CHECK_DWCPM_PS ,
  2922. IDC_CHECK_DCLPM_PS ,
  2923. IDC_CHECK_DCCPM_PS ,
  2924. IDC_CHECK_DCCM_PS ,
  2925. IDC_CHECK_DCAM_PS ,
  2926. IDC_CHECK_CCDL_PS ,
  2927. IDC_CHECK_CCPL_PS ,
  2928. IDC_CHECK_DMCP_PS ,
  2929. IDC_CHECK_CONCLIENT_INHERIT,
  2930. IDC_CHECK_COLORDEPTH_OVERRIDE,
  2931. IDC_COLORDEPTH_OVERRIDE,
  2932. -1
  2933. };
  2934. EnableGroup( hDlg , &rgID[ 0 ] , FALSE );
  2935. }
  2936. }
  2937. pCfgcomp->Release( );
  2938. m_bPersisted = TRUE;
  2939. return CDialogPropBase::OnInitDialog( hDlg , wp , lp );
  2940. }
  2941. //-----------------------------------------------------------------------------
  2942. //Disable fields if a group policy is set
  2943. void CClient::DetermineFieldEnabling(HWND hDlg)
  2944. {
  2945. POLICY_TS_MACHINE p;
  2946. RegGetMachinePolicy(&p);
  2947. //Mapping fields
  2948. //EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DMCP_PS), !p.fPolicyForceClientLptDef); //Done below since it depends on 2 things
  2949. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCDM_PS), !p.fPolicyDisableCdm);
  2950. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DWCPM_PS), !p.fPolicyDisableCpm);
  2951. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCLPM_PS), !p.fPolicyDisableLPT);
  2952. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCCPM_PS), !p.fPolicyDisableCcm);
  2953. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCCM_PS), !p.fPolicyDisableClip);
  2954. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_DCAM_PS), !p.fPolicyDisableCam);
  2955. //Connection fields
  2956. BOOL bEnableConnectionSettings = (SendMessage(GetDlgItem(hDlg, IDC_CHECK_CONCLIENT_INHERIT), BM_GETCHECK, 0, 0) != BST_CHECKED);
  2957. // check to see if client drive mapping is selected if so disable
  2958. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_CCDL_PS), bEnableConnectionSettings &&
  2959. (SendMessage(GetDlgItem(hDlg, IDC_CHECK_DCDM_PS), BM_GETCHECK, 0, 0) != BST_CHECKED));
  2960. EnableWindow( GetDlgItem( hDlg , IDC_CHECK_CCPL_PS ) , bEnableConnectionSettings );
  2961. EnableWindow( GetDlgItem( hDlg , IDC_CHECK_DMCP_PS ) , bEnableConnectionSettings && !p.fPolicyForceClientLptDef);
  2962. //Color Depth fields
  2963. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_COLORDEPTH_OVERRIDE), (!p.fPolicyColorDepth));
  2964. BOOL bEnableColorDepthSetting = SendMessage( GetDlgItem( hDlg , IDC_CHECK_COLORDEPTH_OVERRIDE ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED;
  2965. EnableWindow(GetDlgItem(hDlg, IDC_COLORDEPTH_OVERRIDE), (bEnableColorDepthSetting && !p.fPolicyColorDepth));
  2966. }
  2967. //-----------------------------------------------------------------------------
  2968. void CClient::SetColorDepthEntry(HWND hwnd)
  2969. {
  2970. BOOL bEnableColorDepthSetting = TRUE;
  2971. // check to see if override Color Depth setting is checked
  2972. bEnableColorDepthSetting = SendMessage( GetDlgItem( hwnd , IDC_CHECK_COLORDEPTH_OVERRIDE ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED;
  2973. //Select the correct combo box entry
  2974. if (bEnableColorDepthSetting)
  2975. {
  2976. //Select the correct value in the combo box based on the current value
  2977. INT_PTR iColorDepthListCount = 0;
  2978. iColorDepthListCount = SendMessage( GetDlgItem( hwnd, IDC_COLORDEPTH_OVERRIDE ), CB_GETCOUNT , 0 , 0 );
  2979. //Traverse the list looking an entry with value equal to m_nColorDepth
  2980. for (int iColorDepthListIndex = 0; iColorDepthListIndex < iColorDepthListCount; iColorDepthListIndex++)
  2981. {
  2982. INT_PTR iMatchingColorDepthValue = 0;
  2983. iMatchingColorDepthValue = SendMessage( GetDlgItem( hwnd, IDC_COLORDEPTH_OVERRIDE ), CB_GETITEMDATA , iColorDepthListIndex , 0 ) ;
  2984. if (iMatchingColorDepthValue == m_nColorDepth )
  2985. {
  2986. //Value found, set the combo box selection to the correct index
  2987. SendMessage( GetDlgItem( hwnd, IDC_COLORDEPTH_OVERRIDE ), CB_SETCURSEL , iColorDepthListIndex , 0 );
  2988. break;
  2989. }
  2990. }
  2991. //Make sure something's been selected - if not, just select the first value in the list
  2992. INT_PTR iSelection = SendMessage ( GetDlgItem( hwnd, IDC_COLORDEPTH_OVERRIDE ), CB_GETCURSEL, 0, 0 );
  2993. if (iSelection == CB_ERR)
  2994. SendMessage( GetDlgItem( hwnd, IDC_COLORDEPTH_OVERRIDE ), CB_SETCURSEL , 0 , 0 );
  2995. }
  2996. else
  2997. {
  2998. //Clear the contents of the combo box window if the color depth isn't editable
  2999. SendMessage( GetDlgItem( hwnd, IDC_COLORDEPTH_OVERRIDE ), CB_SETCURSEL , (WPARAM)CB_ERR , 0 );
  3000. }
  3001. }
  3002. //-----------------------------------------------------------------------------
  3003. BOOL CClient::PersistSettings( HWND hDlg )
  3004. {
  3005. if( m_pParent == NULL )
  3006. {
  3007. return FALSE;
  3008. }
  3009. USERCONFIG uc;
  3010. if( !m_pParent->GetCurrentUserConfig( uc, TRUE ) )
  3011. {
  3012. return FALSE;
  3013. }
  3014. uc.fInheritAutoClient = SendMessage( GetDlgItem( hDlg , IDC_CHECK_CONCLIENT_INHERIT ) , BM_GETCHECK , 0 , 0 );
  3015. if( !uc.fInheritAutoClient )
  3016. {
  3017. uc.fAutoClientDrives = SendMessage( GetDlgItem( hDlg , IDC_CHECK_CCDL_PS ) , BM_GETCHECK , 0 , 0 );
  3018. uc.fAutoClientLpts = SendMessage( GetDlgItem( hDlg , IDC_CHECK_CCPL_PS ) , BM_GETCHECK , 0 , 0 );
  3019. uc.fForceClientLptDef = SendMessage( GetDlgItem( hDlg , IDC_CHECK_DMCP_PS ) , BM_GETCHECK , 0 , 0 );
  3020. }
  3021. uc.fDisableCdm = SendMessage( GetDlgItem( hDlg , IDC_CHECK_DCDM_PS ) , BM_GETCHECK , 0 , 0 );
  3022. uc.fDisableCpm = SendMessage( GetDlgItem( hDlg , IDC_CHECK_DWCPM_PS ) , BM_GETCHECK , 0 , 0 );
  3023. uc.fDisableLPT = SendMessage( GetDlgItem( hDlg , IDC_CHECK_DCLPM_PS ) , BM_GETCHECK , 0 , 0 );
  3024. uc.fDisableCcm = SendMessage( GetDlgItem( hDlg , IDC_CHECK_DCCPM_PS ) , BM_GETCHECK , 0 , 0 );
  3025. uc.fDisableClip = SendMessage( GetDlgItem( hDlg , IDC_CHECK_DCCM_PS ) , BM_GETCHECK , 0 , 0 );
  3026. uc.fDisableCam = SendMessage( GetDlgItem( hDlg , IDC_CHECK_DCAM_PS ) , BM_GETCHECK , 0 , 0 );
  3027. uc.fInheritColorDepth = (( ULONG )SendMessage( GetDlgItem( hDlg , IDC_CHECK_COLORDEPTH_OVERRIDE ) , BM_GETCHECK , 0 , 0 )) == BST_UNCHECKED;
  3028. if( !uc.fInheritColorDepth )
  3029. {
  3030. INT_PTR iColorDepthSel = CB_ERR;
  3031. iColorDepthSel = SendMessage( GetDlgItem( hDlg , IDC_COLORDEPTH_OVERRIDE ) , CB_GETCURSEL, 0 , 0 );
  3032. INT_PTR iColorDepthValue = 0;
  3033. iColorDepthValue = SendMessage( GetDlgItem( hDlg , IDC_COLORDEPTH_OVERRIDE ) , CB_GETITEMDATA , iColorDepthSel , 0 );
  3034. uc.ColorDepth = iColorDepthValue;
  3035. }
  3036. else
  3037. {
  3038. uc.ColorDepth = TS_24BPP_SUPPORT;
  3039. }
  3040. DWORD dwStatus;
  3041. if( FAILED( m_pParent->SetUserConfig( uc , &dwStatus ) ) )
  3042. {
  3043. ReportStatusError( hDlg , dwStatus );
  3044. return FALSE;
  3045. }
  3046. ICfgComp *pCfgcomp = NULL;
  3047. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) > 0 )
  3048. {
  3049. VERIFY_S( S_OK , pCfgcomp->ForceUpdate( ) );
  3050. VERIFY_S( S_OK , pCfgcomp->Refresh( ) );
  3051. // global flag can only be set to true
  3052. m_pParent->m_bPropertiesChange = TRUE;
  3053. pCfgcomp->Release( );
  3054. }
  3055. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  3056. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  3057. return TRUE;
  3058. }
  3059. //-----------------------------------------------------------------------------
  3060. INT_PTR CALLBACK CClient::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  3061. {
  3062. CClient *pDlg;
  3063. if( msg == WM_INITDIALOG )
  3064. {
  3065. CClient *pDlg = ( CClient * )( ( PROPSHEETPAGE *)lp )->lParam ;
  3066. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  3067. if( !IsBadReadPtr( pDlg , sizeof( CClient ) ) )
  3068. {
  3069. pDlg->OnInitDialog( hwnd , wp , lp );
  3070. }
  3071. return 0;
  3072. }
  3073. else
  3074. {
  3075. pDlg = ( CClient * )GetWindowLongPtr( hwnd , DWLP_USER );
  3076. if( IsBadReadPtr( pDlg , sizeof( CClient ) ) )
  3077. {
  3078. return FALSE;
  3079. }
  3080. }
  3081. switch( msg )
  3082. {
  3083. case WM_NCDESTROY:
  3084. pDlg->OnDestroy( );
  3085. break;
  3086. case WM_COMMAND:
  3087. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  3088. break;
  3089. case WM_CONTEXTMENU:
  3090. {
  3091. POINT pt;
  3092. pt.x = LOWORD( lp );
  3093. pt.y = HIWORD( lp );
  3094. pDlg->OnContextMenu( ( HWND )wp , pt );
  3095. }
  3096. break;
  3097. case WM_HELP:
  3098. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  3099. break;
  3100. case WM_NOTIFY:
  3101. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  3102. break;
  3103. }
  3104. return FALSE;
  3105. }
  3106. //-----------------------------------------------------------------------------
  3107. BOOL CClient::GetPropertySheetPage( PROPSHEETPAGE& psp )
  3108. {
  3109. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  3110. psp.dwSize = sizeof( PROPSHEETPAGE );
  3111. psp.dwFlags = PSP_DEFAULT;
  3112. psp.hInstance = _Module.GetResourceInstance( );
  3113. psp.pszTemplate = MAKEINTRESOURCE( IDD_TSCC_CLIENT );
  3114. psp.lParam = ( LPARAM )this;
  3115. psp.pfnDlgProc = CClient::DlgProc;
  3116. return TRUE;
  3117. }
  3118. //-----------------------------------------------------------------------------
  3119. BOOL CClient::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  3120. {
  3121. if( wNotifyCode == BN_CLICKED )
  3122. {
  3123. if ((wID == IDC_CHECK_CONCLIENT_INHERIT) || (wID == IDC_CHECK_COLORDEPTH_OVERRIDE) ||
  3124. (wID == IDC_CHECK_DWCPM_PS ) || (wID == IDC_CHECK_DCDM_PS))
  3125. {
  3126. DetermineFieldEnabling(GetParent(hwndCtrl));
  3127. }
  3128. if (wID == IDC_CHECK_COLORDEPTH_OVERRIDE)
  3129. SetColorDepthEntry(GetParent(hwndCtrl));
  3130. }
  3131. else if( wNotifyCode == ALN_APPLY )
  3132. {
  3133. SendMessage( GetParent( hwndCtrl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  3134. return FALSE;
  3135. }
  3136. m_bPersisted = FALSE;
  3137. SendMessage( GetParent( GetParent( hwndCtrl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtrl ) , 0 );
  3138. return FALSE;
  3139. }
  3140. //-----------------------------------------------------------------------------
  3141. BOOL CClient::OnDestroy( )
  3142. {
  3143. m_pParent->Release( );
  3144. return TRUE;
  3145. }
  3146. /*************************************************************************************************************************/
  3147. /*EXTERN_C const GUID IID_ISecurityInformation =
  3148. { 0x965fc360, 0x16ff, 0x11d0, 0x91, 0xcb, 0x0, 0xaa, 0x0, 0xbb, 0xb7, 0x23 };
  3149. */
  3150. //
  3151. // WinStation General Permissions
  3152. //
  3153. /*
  3154. SI_ACCESS siWinStationAccesses[] =
  3155. {
  3156. { &GUID_NULL , WINSTATION_QUERY , NULL ,SI_ACCESS_SPECIFIC },
  3157. { &GUID_NULL , WINSTATION_SET , NULL ,SI_ACCESS_SPECIFIC },
  3158. { &GUID_NULL , WINSTATION_RESET , NULL ,SI_ACCESS_SPECIFIC },
  3159. { &GUID_NULL , WINSTATION_SHADOW , NULL ,SI_ACCESS_SPECIFIC },
  3160. { &GUID_NULL , WINSTATION_LOGON , NULL ,SI_ACCESS_SPECIFIC },
  3161. { &GUID_NULL , WINSTATION_LOGOFF , NULL ,SI_ACCESS_SPECIFIC },
  3162. { &GUID_NULL , WINSTATION_MSG , NULL ,SI_ACCESS_SPECIFIC },
  3163. { &GUID_NULL , WINSTATION_CONNECT , NULL ,SI_ACCESS_SPECIFIC },
  3164. { &GUID_NULL , WINSTATION_DISCONNECT , NULL , SI_ACCESS_SPECIFIC},
  3165. { &GUID_NULL , WINSTATION_VIRTUAL | STANDARD_RIGHTS_REQUIRED, NULL , SI_ACCESS_SPECIFIC},
  3166. { &GUID_NULL , WINSTATION_ALL_ACCESS , NULL , SI_ACCESS_GENERAL },
  3167. { &GUID_NULL , WINSTATION_USER_ACCESS , NULL , SI_ACCESS_GENERAL },
  3168. { &GUID_NULL , WINSTATION_GUEST_ACCESS , NULL , SI_ACCESS_GENERAL }
  3169. };
  3170. */
  3171. SI_ACCESS siWinStationAccesses[] =
  3172. {
  3173. { &GUID_NULL , WINSTATION_QUERY , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_QUERY ),SI_ACCESS_SPECIFIC },
  3174. { &GUID_NULL , WINSTATION_SET , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_SET ) ,SI_ACCESS_SPECIFIC },
  3175. //{ &GUID_NULL , WINSTATION_RESET , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_RESET ) ,SI_ACCESS_SPECIFIC },
  3176. { &GUID_NULL , WINSTATION_SHADOW , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_SHADOW ) ,SI_ACCESS_SPECIFIC },
  3177. { &GUID_NULL , WINSTATION_LOGON , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_LOGON ) ,SI_ACCESS_SPECIFIC },
  3178. { &GUID_NULL , WINSTATION_RESET , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_LOGOFF ) ,SI_ACCESS_SPECIFIC },
  3179. { &GUID_NULL , WINSTATION_MSG , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_MSG ) ,SI_ACCESS_SPECIFIC },
  3180. { &GUID_NULL , WINSTATION_CONNECT , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_CONNECT ) ,SI_ACCESS_SPECIFIC },
  3181. { &GUID_NULL , WINSTATION_DISCONNECT , MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_DISCONNECT ) , SI_ACCESS_SPECIFIC},
  3182. { &GUID_NULL , WINSTATION_VIRTUAL | STANDARD_RIGHTS_REQUIRED, MAKEINTRESOURCE ( IDS_PERMS_SPECIAL_DELETE ) , SI_ACCESS_SPECIFIC},
  3183. { &GUID_NULL , WINSTATION_ALL_ACCESS , MAKEINTRESOURCE ( IDS_PERMS_RESOURCE_ADMIN ) , SI_ACCESS_GENERAL },
  3184. { &GUID_NULL , WINSTATION_USER_ACCESS , MAKEINTRESOURCE ( IDS_PERMS_RESOURCE_USER ) , SI_ACCESS_GENERAL },
  3185. { &GUID_NULL , WINSTATION_GUEST_ACCESS , MAKEINTRESOURCE ( IDS_PERMS_RESOURCE_GUEST ) , SI_ACCESS_GENERAL }
  3186. };
  3187. #define MAX_PERM 12
  3188. #define iWinStationDefAccess 11 // index of value in array siWinStationAccesses
  3189. //-----------------------------------------------------------------------------
  3190. STDMETHODIMP CSecurityPage::GetAccessRights(
  3191. const GUID *pguidObjectType,
  3192. DWORD dwFlags,
  3193. PSI_ACCESS *ppAccess,
  3194. PULONG pcAccesses,
  3195. PULONG piDefaultAccess
  3196. )
  3197. {
  3198. UNREFERENCED_PARAMETER( dwFlags );
  3199. UNREFERENCED_PARAMETER( pguidObjectType );
  3200. ASSERT( ppAccess != NULL );
  3201. ASSERT( pcAccesses != NULL );
  3202. ASSERT( piDefaultAccess != NULL );
  3203. *ppAccess = siWinStationAccesses;
  3204. *pcAccesses = MAX_PERM;
  3205. *piDefaultAccess = iWinStationDefAccess;
  3206. return S_OK;
  3207. }
  3208. //-----------------------------------------------------------------------------
  3209. // This is consistent with the termsrv code
  3210. //-----------------------------------------------------------------------------
  3211. GENERIC_MAPPING WinStationMap =
  3212. {
  3213. WINSTATION_QUERY , /* GenericRead */
  3214. WINSTATION_USER_ACCESS, /* GenericWrite */
  3215. WINSTATION_USER_ACCESS, /* GenericExecute */
  3216. WINSTATION_ALL_ACCESS /* GenericAll */
  3217. };
  3218. //-----------------------------------------------------------------------------
  3219. void CSecurityPage::SetParent( CPropsheet *pParent )
  3220. {
  3221. m_pParent = pParent;
  3222. }
  3223. //-----------------------------------------------------------------------------
  3224. STDMETHODIMP CSecurityPage::MapGeneric( const GUID *pguidObjectType , PUCHAR pAceFlags , ACCESS_MASK *pMask )
  3225. {
  3226. UNREFERENCED_PARAMETER( pguidObjectType );
  3227. UNREFERENCED_PARAMETER( pAceFlags );
  3228. ASSERT( pMask != NULL );
  3229. MapGenericMask( pMask , &WinStationMap );
  3230. return S_OK;
  3231. }
  3232. //-----------------------------------------------------------------------------
  3233. STDMETHODIMP CSecurityPage::GetInheritTypes( PSI_INHERIT_TYPE *ppInheritTypes , PULONG pcInheritTypes )
  3234. {
  3235. UNREFERENCED_PARAMETER( ppInheritTypes );
  3236. UNREFERENCED_PARAMETER( pcInheritTypes );
  3237. return E_NOTIMPL;
  3238. }
  3239. //-----------------------------------------------------------------------------
  3240. STDMETHODIMP CSecurityPage::PropertySheetPageCallback( HWND hwnd , UINT uMsg , SI_PAGE_TYPE uPage )
  3241. {
  3242. UNREFERENCED_PARAMETER( hwnd );
  3243. UNREFERENCED_PARAMETER( uPage );
  3244. if( uMsg == PSPCB_SI_INITDIALOG )
  3245. {
  3246. ODS( L"CSecurityPage::PropertySheetPageCallback -- Init\n" );
  3247. if (!m_WritablePermissionsTab )
  3248. {
  3249. LinkWindow_RegisterClass();
  3250. DialogBox( _Module.GetResourceInstance( ), MAKEINTRESOURCE(IDD_CUSTOM_SECURITY),
  3251. hwnd, CustomSecurityDlgProc);
  3252. LinkWindow_UnregisterClass(_Module.GetModuleInstance( ));
  3253. }
  3254. }
  3255. else if( uMsg == PSPCB_RELEASE )
  3256. {
  3257. ODS( L"CSecurityPage::PropertySheetPageCallback -- Release\n" );
  3258. }
  3259. return S_FALSE; //Be sure to return S_FALSE, This supresses other popups.
  3260. }
  3261. /*
  3262. Change to TSCC's permissions TAB such that the default state is READ-ONLY unless
  3263. group policy is used to override it.
  3264. If TRUE, permissions TAB can be edited by local Adimn.
  3265. if FALSE, the local Admin should not edit permissions TAB, it is read only
  3266. */
  3267. BOOLEAN QueryWriteAccess()
  3268. {
  3269. DWORD ValueType;
  3270. DWORD ValueSize = sizeof(DWORD);
  3271. DWORD valueData ;
  3272. LONG errorCode;
  3273. HKEY hTSControlKey = NULL;
  3274. //
  3275. // first check the policy tree,
  3276. //
  3277. POLICY_TS_MACHINE p;
  3278. RegGetMachinePolicy(&p);
  3279. if ( p.fPolicyWritableTSCCPermissionsTAB )
  3280. {
  3281. return (BOOLEAN)( p.fWritableTSCCPermissionsTAB ? TRUE : FALSE );
  3282. }
  3283. // if we got this far, then no policy was set. Check the local machine now.
  3284. errorCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CONTROL_TSERVER, 0,
  3285. KEY_READ, &hTSControlKey );
  3286. if ( ( errorCode == ERROR_SUCCESS ) && hTSControlKey )
  3287. {
  3288. errorCode = RegQueryValueEx( hTSControlKey,
  3289. POLICY_TS_TSCC_PERM_TAB_WRITABLE , NULL, &ValueType,
  3290. (LPBYTE) &valueData, &ValueSize );
  3291. RegCloseKey(hTSControlKey);
  3292. if (errorCode == ERROR_SUCCESS )
  3293. {
  3294. return (BOOLEAN)( valueData ? TRUE : FALSE ) ;
  3295. }
  3296. }
  3297. // if no localKey, gee... the registry is missing data... return FALSE to be on the secure side
  3298. return FALSE;
  3299. }
  3300. /*-----------------------------------------------------------------------------
  3301. JeffreyS 1/24/97:
  3302. If you don't set the SI_RESET flag in
  3303. ISecurityInformation::GetObjectInformation, then fDefault should never be TRUE
  3304. so you can ignore it. Returning E_NOTIMPL in this case is OK too.
  3305. If you want the user to be able to reset the ACL to some default state
  3306. (defined by you) then turn on SI_RESET and return your default ACL
  3307. when fDefault is TRUE. This happens if/when the user pushes a button
  3308. that is only visible when SI_RESET is on.
  3309. -----------------------------------------------------------------------------*/
  3310. STDMETHODIMP CSecurityPage::GetObjectInformation( PSI_OBJECT_INFO pObjectInfo )
  3311. {
  3312. ASSERT( pObjectInfo != NULL && !IsBadWritePtr(pObjectInfo, sizeof(*pObjectInfo ) ) );
  3313. pObjectInfo->dwFlags = SI_OWNER_READONLY | SI_EDIT_PERMS | SI_NO_ACL_PROTECT | SI_PAGE_TITLE | SI_EDIT_AUDITS | SI_ADVANCED | SI_RESET;
  3314. m_WritablePermissionsTab = QueryWriteAccess() ;
  3315. if( ! m_WritablePermissionsTab ) {
  3316. pObjectInfo->dwFlags |= SI_READONLY;
  3317. }
  3318. pObjectInfo->hInstance = _Module.GetResourceInstance( );
  3319. pObjectInfo->pszServerName = NULL;
  3320. pObjectInfo->pszObjectName = m_pParent->m_pResNode->GetConName();
  3321. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_SECURPAGENAME , m_szPageName , SIZE_OF_BUFFER( m_szPageName ) ) );
  3322. pObjectInfo->pszPageTitle = m_szPageName;
  3323. return S_OK;
  3324. }
  3325. //-----------------------------------------------------------------------------
  3326. STDMETHODIMP CSecurityPage::GetSecurity( SECURITY_INFORMATION RequestedInformation , PSECURITY_DESCRIPTOR *ppSecurityDescriptor , BOOL bDefault )
  3327. {
  3328. #ifdef DBG
  3329. if( RequestedInformation & OWNER_SECURITY_INFORMATION )
  3330. {
  3331. ODS( L"CSecurityPage::GetSecurity - OWNER_SECURITY_INFORMATION\n");
  3332. }
  3333. if( RequestedInformation & GROUP_SECURITY_INFORMATION )
  3334. {
  3335. ODS( L"CSecurityPage::GetSecurity - GROUP_SECURITY_INFORMATION\n");
  3336. }
  3337. if( RequestedInformation & DACL_SECURITY_INFORMATION )
  3338. {
  3339. ODS( L"CSecurityPage::GetSecurity - DACL_SECURITY_INFORMATION\n");
  3340. }
  3341. if( RequestedInformation & SACL_SECURITY_INFORMATION )
  3342. {
  3343. ODS( L"CSecurityPage::GetSecurity - SACL_SECURITY_INFORMATION\n");
  3344. }
  3345. #endif
  3346. if( 0 == RequestedInformation || NULL == ppSecurityDescriptor )
  3347. {
  3348. ASSERT( FALSE );
  3349. return E_INVALIDARG;
  3350. }
  3351. ICfgComp *pCfgcomp = NULL;
  3352. if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0 )
  3353. {
  3354. return FALSE;
  3355. }
  3356. LONG lSDsize;
  3357. HRESULT hr;
  3358. PSECURITY_DESCRIPTOR pSD = NULL;
  3359. if( bDefault )
  3360. {
  3361. hr = pCfgcomp->GetDefaultSecurityDescriptor( &lSDsize , &pSD );
  3362. *ppSecurityDescriptor = pSD;
  3363. }
  3364. else
  3365. {
  3366. BOOL bChanged = FALSE;
  3367. hr = pCfgcomp->GetSecurityDescriptor( m_pParent->m_pResNode->GetConName( ) , &lSDsize , &pSD );
  3368. // check for legacy "denied logoff" ace and remove.
  3369. if( xxxLegacyLogoffCleanup( &pSD , &bChanged ) != ERROR_SUCCESS )
  3370. {
  3371. hr = pCfgcomp->GetDefaultSecurityDescriptor( &lSDsize , &pSD );
  3372. }
  3373. *ppSecurityDescriptor = pSD;
  3374. }
  3375. pCfgcomp->Release( );
  3376. if(SUCCEEDED(hr))
  3377. {
  3378. MakeLocalSDCopy( *ppSecurityDescriptor );
  3379. }
  3380. return hr;
  3381. }
  3382. //-----------------------------------------------------------------------------
  3383. STDMETHODIMP CSecurityPage::SetSecurity( SECURITY_INFORMATION SecurityInformation ,PSECURITY_DESCRIPTOR pSecurityDescriptor )
  3384. {
  3385. HRESULT hr = S_OK;
  3386. ICfgComp *pCfgcomp = NULL;
  3387. PSECURITY_DESCRIPTOR pSD1;
  3388. if( m_pParent == NULL || m_pParent->m_pResNode == NULL )
  3389. {
  3390. hr = E_UNEXPECTED;
  3391. }
  3392. else if( m_pParent->m_pResNode->GetServer( &pCfgcomp ) != 0 )
  3393. {
  3394. long lSDsize;
  3395. hr = pCfgcomp->GetSecurityDescriptor( m_pParent->m_pResNode->GetConName( ) , &lSDsize , &pSD1 );
  3396. if( FAILED( hr ) )
  3397. {
  3398. pCfgcomp->Release( );
  3399. return hr;
  3400. }
  3401. SECURITY_DESCRIPTOR_CONTROL sdc;
  3402. DWORD dwREV;
  3403. PACL pDacl = NULL;
  3404. PACL pSacl = NULL;
  3405. SECURITY_DESCRIPTOR absSD;
  3406. BOOL bSaclPresent = FALSE;
  3407. BOOL bSaclDefaulted = FALSE;
  3408. BOOL bDaclPresent = FALSE;
  3409. BOOL bDaclDefaulted = FALSE;
  3410. //
  3411. // Convert SelfRel to Absolute
  3412. // ignore owner and group
  3413. //
  3414. GetSecurityDescriptorControl( pSD1 , &sdc , &dwREV );
  3415. if( !InitializeSecurityDescriptor( &absSD , dwREV ) )
  3416. {
  3417. DBGMSG( L"TSCC!CSecurityPage_SetSecurity InitializeSecurityDescriptor failed with 0x%x\n" , GetLastError( ) );
  3418. return E_FAIL;
  3419. }
  3420. GetSecurityDescriptorDacl( pSD1 , &bDaclPresent , &pDacl , &bDaclDefaulted );
  3421. SetSecurityDescriptorDacl( &absSD , bDaclPresent , pDacl , bDaclDefaulted );
  3422. GetSecurityDescriptorSacl( pSD1 , &bSaclPresent , &pSacl , &bSaclDefaulted );
  3423. SetSecurityDescriptorSacl( &absSD , bSaclPresent , pSacl , bSaclDefaulted );
  3424. // now call SetDACL or SACL depending on SecurityInformation
  3425. if( SecurityInformation & OWNER_SECURITY_INFORMATION )
  3426. {
  3427. ODS( L"CSecurityPage::SetSecurity - OWNER_SECURITY_INFORMATION ( default value set )\n");
  3428. }
  3429. if( SecurityInformation & GROUP_SECURITY_INFORMATION )
  3430. {
  3431. ODS( L"CSecurityPage::SetSecurity - GROUP_SECURITY_INFORMATION ( default value set )\n");
  3432. }
  3433. if( SecurityInformation & DACL_SECURITY_INFORMATION )
  3434. {
  3435. ODS( L"CSecurityPage::SetSecurity - DACL_SECURITY_INFORMATION\n");
  3436. GetSecurityDescriptorDacl( pSecurityDescriptor , &bDaclPresent , &pDacl , &bDaclDefaulted );
  3437. SetSecurityDescriptorDacl( &absSD , bDaclPresent , pDacl , bDaclDefaulted );
  3438. }
  3439. if( SecurityInformation & SACL_SECURITY_INFORMATION )
  3440. {
  3441. ODS( L"CSecurityPage::SetSecurity - SACL_SECURITY_INFORMATION\n");
  3442. GetSecurityDescriptorSacl( pSecurityDescriptor , &bSaclPresent , &pSacl , &bSaclDefaulted );
  3443. SetSecurityDescriptorSacl( &absSD , bSaclPresent , pSacl , bSaclDefaulted );
  3444. }
  3445. PSID SystemSid = NULL;
  3446. SID_IDENTIFIER_AUTHORITY NtSidAuthority = SECURITY_NT_AUTHORITY;
  3447. hr = E_OUTOFMEMORY;
  3448. if( AllocateAndInitializeSid( &NtSidAuthority,
  3449. 1,
  3450. SECURITY_LOCAL_SYSTEM_RID,
  3451. 0, 0, 0, 0, 0, 0, 0,
  3452. &SystemSid ) )
  3453. {
  3454. if( SystemSid != NULL )
  3455. {
  3456. hr = S_OK;
  3457. }
  3458. }
  3459. PSECURITY_DESCRIPTOR pSD = NULL;
  3460. DWORD dwSDLen;
  3461. if( SUCCEEDED( hr ) )
  3462. {
  3463. VERIFY_S( TRUE , SetSecurityDescriptorOwner( &absSD , SystemSid , FALSE ) );
  3464. VERIFY_S( TRUE, SetSecurityDescriptorGroup( &absSD , SystemSid , FALSE ) );
  3465. dwSDLen = 0;
  3466. MakeSelfRelativeSD( &absSD, pSD, &dwSDLen);
  3467. if (dwSDLen != 0)
  3468. {
  3469. pSD = ( LPBYTE )new BYTE[ dwSDLen ];
  3470. }
  3471. }
  3472. if( pSD == NULL )
  3473. {
  3474. ODS( L"TSCC!CSecurityPage::SetSecurity - SD allocation failed\n" );
  3475. hr = E_OUTOFMEMORY;
  3476. }
  3477. if( SUCCEEDED( hr ) )
  3478. {
  3479. if( !MakeSelfRelativeSD( &absSD , pSD , &dwSDLen ) )
  3480. {
  3481. hr = E_UNEXPECTED;
  3482. DBGMSG( L"MakeSelfRelativeSD - failed in CSecurityPage::SetSecurity With error %x\n" , GetLastError( ) );
  3483. }
  3484. if( SUCCEEDED( hr ) )
  3485. {
  3486. hr = pCfgcomp->SetSecurityDescriptor( m_pParent->m_pResNode->GetConName( ) , dwSDLen , pSD );
  3487. }
  3488. if( SUCCEEDED( hr ) )
  3489. {
  3490. ODS( L"TSCC : Update SD for TERMSRV\n" );
  3491. hr = pCfgcomp->ForceUpdate( );
  3492. // global flag can only be set to true
  3493. m_pParent->m_bPropertiesChange = TRUE;
  3494. UpdateTSLogonRight(m_pParent->m_pResNode->GetConName( ), pSD);
  3495. }
  3496. delete[] pSD;
  3497. }
  3498. if( SystemSid != NULL )
  3499. {
  3500. FreeSid( SystemSid );
  3501. }
  3502. // free originally stored SD.
  3503. LocalFree( pSD1 );
  3504. pCfgcomp->Release( );
  3505. }
  3506. return hr;
  3507. }
  3508. //*************************************************************
  3509. //
  3510. // CSecurityPage::MakeLocalSDCopy()
  3511. //
  3512. // Purpose: Makes a copy of the original SD.
  3513. // We'll need it for comparing with SD returned
  3514. // by Access Control Editor.
  3515. //
  3516. // Parameters: IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  3517. //
  3518. // Return: NONE
  3519. //
  3520. // Comments:
  3521. //
  3522. // History: Date Author Comment
  3523. // 6/19/01 skuzin Created
  3524. //
  3525. //*************************************************************
  3526. void
  3527. CSecurityPage::MakeLocalSDCopy(
  3528. IN PSECURITY_DESCRIPTOR pSecurityDescriptor )
  3529. {
  3530. if(m_pOriginalSD)
  3531. {
  3532. delete m_pOriginalSD;
  3533. }
  3534. DWORD dwSDLength = GetSecurityDescriptorLength(pSecurityDescriptor);
  3535. m_pOriginalSD = (PSECURITY_DESCRIPTOR)new BYTE[dwSDLength];
  3536. if(m_pOriginalSD)
  3537. {
  3538. CopyMemory(m_pOriginalSD, pSecurityDescriptor, dwSDLength);
  3539. }
  3540. }
  3541. //*************************************************************
  3542. //
  3543. // CSecurityPage::UpdateTSLogonRight()
  3544. //
  3545. // Purpose: Grants SE_REMOTE_INTERACTIVE_LOGON_NAME right to all users,
  3546. // who gained Logon permission, but does not have this right yet.
  3547. // Revokes SE_REMOTE_INTERACTIVE_LOGON_NAME right from all users,
  3548. // who lost Logon permission and don't have Logon permission to
  3549. // any other winstation (connection).
  3550. //
  3551. // Parameters: IN PWINSTATIONNAMEW pWSName - connection name
  3552. // IN PSECURITY_DESCRIPTOR pSecurityDescriptor -
  3553. // new security descriptor
  3554. //
  3555. // Return: NONE
  3556. //
  3557. // Comments:
  3558. //
  3559. // History: Date Author Comment
  3560. // 6/19/01 skuzin Created
  3561. //
  3562. //*************************************************************
  3563. void
  3564. CSecurityPage::UpdateTSLogonRight(
  3565. IN PWINSTATIONNAMEW pWSName,
  3566. IN PSECURITY_DESCRIPTOR pSecurityDescriptor )
  3567. {
  3568. PSID *ppLogonAllowSIDs = NULL, *ppLogonDenySIDs = NULL;
  3569. DWORD cLogonAllowSIDs = 0, cLogonDenySIDs = 0;
  3570. //No SD to compare to. Do nothing.
  3571. if(!m_pOriginalSD)
  3572. {
  3573. return;
  3574. }
  3575. //Get Everyone's SID. All subsequent functions implicitly use it.
  3576. SID_IDENTIFIER_AUTHORITY WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
  3577. if(!AllocateAndInitializeSid( &WorldSidAuthority, 1,
  3578. SECURITY_WORLD_RID,
  3579. 0, 0, 0, 0, 0, 0, 0,
  3580. &m_pWorldSid ))
  3581. {
  3582. return;
  3583. }
  3584. //Get SIDs of all users, who have gained or lost Logon permission.
  3585. if(!GetChangedUsers(pSecurityDescriptor, ppLogonAllowSIDs, ppLogonDenySIDs,
  3586. &cLogonAllowSIDs, &cLogonDenySIDs))
  3587. {
  3588. FreeSid(m_pWorldSid);
  3589. m_pWorldSid = NULL;
  3590. return;
  3591. }
  3592. PSID *ppLogonRightSIDs;
  3593. DWORD cLogonRightSIDs = 0;
  3594. DWORD i, j;
  3595. //Get SIDs of all users who have SE_REMOTE_INTERACTIVE_LOGON_NAME right.
  3596. if(GetUsersWhoAlreadyHasTSLogonRight(ppLogonRightSIDs, &cLogonRightSIDs))
  3597. {
  3598. //Grant SE_REMOTE_INTERACTIVE_LOGON_NAME right to all users who gained Logon
  3599. //permission, but does not have this right yet.
  3600. for(i = 0; i<cLogonAllowSIDs; i++)
  3601. {
  3602. for(j = 0; j<cLogonRightSIDs; j++)
  3603. {
  3604. if(EqualSid(ppLogonAllowSIDs[i],ppLogonRightSIDs[j]))
  3605. {
  3606. break;
  3607. }
  3608. }
  3609. //user does not have this right, let's give it to him.
  3610. if(j == cLogonRightSIDs)
  3611. {
  3612. GrantRightToUser(ppLogonAllowSIDs[i]);
  3613. }
  3614. }
  3615. //Revoke SE_REMOTE_INTERACTIVE_LOGON_NAME right from all users
  3616. //who lost Logon permission and don't have Logon permission to
  3617. //any other winstation (connection).
  3618. for(i = 0; i<cLogonDenySIDs; i++)
  3619. {
  3620. for(j = 0; j<cLogonRightSIDs; j++)
  3621. {
  3622. if(EqualSid(ppLogonDenySIDs[i],ppLogonRightSIDs[j]))
  3623. {
  3624. if(CanRevokeRight(pWSName, ppLogonDenySIDs[i]))
  3625. {
  3626. RevokeRightFromUser(ppLogonDenySIDs[i]);
  3627. }
  3628. }
  3629. }
  3630. }
  3631. }
  3632. if(ppLogonAllowSIDs)
  3633. {
  3634. delete ppLogonAllowSIDs;
  3635. }
  3636. if(ppLogonDenySIDs)
  3637. {
  3638. delete ppLogonDenySIDs;
  3639. }
  3640. if(ppLogonRightSIDs)
  3641. {
  3642. delete ppLogonRightSIDs;
  3643. }
  3644. FreeSid(m_pWorldSid);
  3645. m_pWorldSid = NULL;
  3646. }
  3647. //*************************************************************
  3648. //
  3649. // CSecurityPage::GetChangedUsers()
  3650. //
  3651. // Purpose: Compares original security descriptor with the new one
  3652. // Creates an array of SIDs of all users, who have gained Logon permission,
  3653. // Creates an array of SIDs of all users, who have lost Logon permission,
  3654. //
  3655. // Parameters: PSECURITY_DESCRIPTOR pSecurityDescriptor -
  3656. // new security descriptor to investigate
  3657. // OUT PSID *&ppLogonAllowSIDs - array of SIDs of users,
  3658. // who have gained Logon permission
  3659. // OUT PSID *&ppLogonDenySIDs - array of SIDs of users,
  3660. // who have lost Logon permission
  3661. // OUT LPDWORD pcLogonAllowSIDs - number of entries in ppLogonAllowSIDs
  3662. // OUT LPDWORD pcLogonDenySIDs - number of entries in ppLogonDenySIDs
  3663. //
  3664. // Return: TRUE if success
  3665. // FALSE in case of any error.
  3666. //
  3667. // Comments:
  3668. //
  3669. // History: Date Author Comment
  3670. // 6/19/01 skuzin Created
  3671. //
  3672. //*************************************************************
  3673. BOOL
  3674. CSecurityPage::GetChangedUsers(
  3675. IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
  3676. OUT PSID *&ppLogonAllowSIDs,
  3677. OUT PSID *&ppLogonDenySIDs,
  3678. OUT LPDWORD pcLogonAllowSIDs,
  3679. OUT LPDWORD pcLogonDenySIDs)
  3680. {
  3681. PACL pNewDacl = NULL;
  3682. PACL pOldDacl = NULL;
  3683. BOOL bNewDaclPresent = FALSE;
  3684. BOOL bOldDaclPresent = FALSE;
  3685. BOOL bDaclDefaulted = FALSE;
  3686. ppLogonAllowSIDs = NULL;
  3687. ppLogonDenySIDs = NULL;
  3688. *pcLogonAllowSIDs = 0;
  3689. *pcLogonDenySIDs = 0;
  3690. ASSERT(m_pWorldSid);
  3691. ASSERT(m_pOriginalSD);
  3692. if(!GetSecurityDescriptorDacl(pSecurityDescriptor,&bNewDaclPresent,&pNewDacl,&bDaclDefaulted))
  3693. {
  3694. return FALSE;
  3695. }
  3696. if(!GetSecurityDescriptorDacl(m_pOriginalSD,&bOldDaclPresent,&pOldDacl,&bDaclDefaulted))
  3697. {
  3698. return FALSE;
  3699. }
  3700. ACL_SIZE_INFORMATION asiAclSize;
  3701. DWORD dwBufLength=sizeof(asiAclSize);
  3702. ACCESS_ALLOWED_ACE *pAce;
  3703. DWORD dwAcl_i;
  3704. BOOL bResult = FALSE;
  3705. DWORD dwAllowSIDsIndex = 0;
  3706. if(pNewDacl)
  3707. {
  3708. if (GetAclInformation(pNewDacl,
  3709. (LPVOID)&asiAclSize,
  3710. (DWORD)dwBufLength,
  3711. (ACL_INFORMATION_CLASS)AclSizeInformation))
  3712. {
  3713. ppLogonAllowSIDs = new PSID[asiAclSize.AceCount];
  3714. if(ppLogonAllowSIDs)
  3715. {
  3716. for (dwAcl_i = 0; dwAcl_i < asiAclSize.AceCount; dwAcl_i++)
  3717. {
  3718. if(GetAce( pNewDacl, dwAcl_i, (LPVOID *)&pAce) &&
  3719. pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE &&
  3720. pAce->Mask & WINSTATION_LOGON)
  3721. {
  3722. if(UserHasLogonPermission(pNewDacl,PSID(&pAce->SidStart)) &&
  3723. !UserHasLogonPermission(pOldDacl,PSID(&pAce->SidStart)))
  3724. {
  3725. ppLogonAllowSIDs[dwAllowSIDsIndex] = PSID(&pAce->SidStart);
  3726. dwAllowSIDsIndex++;
  3727. }
  3728. }
  3729. }
  3730. *pcLogonAllowSIDs = dwAllowSIDsIndex;
  3731. bResult = TRUE;
  3732. }
  3733. }
  3734. }
  3735. else
  3736. {
  3737. //No DACL in new SD. Let's if Everyone already had Logon permission
  3738. if(!UserHasLogonPermission(pOldDacl,m_pWorldSid))
  3739. {
  3740. ppLogonAllowSIDs = new PSID[1];
  3741. if(ppLogonAllowSIDs)
  3742. {
  3743. ppLogonAllowSIDs[0] = m_pWorldSid;
  3744. *pcLogonAllowSIDs = 1;
  3745. bResult = TRUE;
  3746. }
  3747. }
  3748. else
  3749. {
  3750. bResult = TRUE;
  3751. }
  3752. }
  3753. if(!bResult)
  3754. {
  3755. return FALSE;
  3756. }
  3757. bResult = FALSE;
  3758. DWORD dwDenySIDsIndex = 0;
  3759. if(pOldDacl)
  3760. {
  3761. if (GetAclInformation(pOldDacl,
  3762. (LPVOID)&asiAclSize,
  3763. (DWORD)dwBufLength,
  3764. (ACL_INFORMATION_CLASS)AclSizeInformation))
  3765. {
  3766. ppLogonDenySIDs = new PSID[asiAclSize.AceCount];
  3767. if(ppLogonDenySIDs)
  3768. {
  3769. for (dwAcl_i = 0; dwAcl_i < asiAclSize.AceCount; dwAcl_i++)
  3770. {
  3771. if(GetAce( pOldDacl, dwAcl_i, (LPVOID *)&pAce) &&
  3772. pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE &&
  3773. pAce->Mask & WINSTATION_LOGON)
  3774. {
  3775. if(UserHasLogonPermission(pOldDacl,PSID(&pAce->SidStart)) &&
  3776. !UserHasLogonPermission(pNewDacl,PSID(&pAce->SidStart)))
  3777. {
  3778. ppLogonDenySIDs[dwDenySIDsIndex] = PSID(&pAce->SidStart);
  3779. dwDenySIDsIndex++;
  3780. }
  3781. }
  3782. }
  3783. *pcLogonDenySIDs = dwDenySIDsIndex;
  3784. bResult = TRUE;
  3785. }
  3786. }
  3787. }
  3788. else
  3789. {
  3790. if(!UserHasLogonPermission(pNewDacl,m_pWorldSid))
  3791. {
  3792. ppLogonDenySIDs = new PSID[1];
  3793. if(ppLogonDenySIDs)
  3794. {
  3795. ppLogonDenySIDs[0] = m_pWorldSid;
  3796. *pcLogonDenySIDs = 1;
  3797. bResult = TRUE;
  3798. }
  3799. }
  3800. else
  3801. {
  3802. bResult = TRUE;
  3803. }
  3804. }
  3805. if(!bResult && ppLogonAllowSIDs)
  3806. {
  3807. delete ppLogonAllowSIDs;
  3808. ppLogonAllowSIDs = NULL;
  3809. *pcLogonAllowSIDs = 0;
  3810. }
  3811. return bResult;
  3812. }
  3813. //*************************************************************
  3814. //
  3815. // CSecurityPage::UserHasLogonPermission()
  3816. //
  3817. // Purpose: Checks if a user represented by a pSid has explicit
  3818. // Logon permission
  3819. //
  3820. // Parameters: PACL pDacl - ACL to search for user
  3821. // PSID pSid - User's SID.
  3822. //
  3823. // Return: TRUE if a user represented by a pSid has explicit
  3824. // Logon permission.
  3825. // FALSE if not, or in case of any error.
  3826. //
  3827. // Comments:
  3828. //
  3829. // History: Date Author Comment
  3830. // 6/19/01 skuzin Created
  3831. //
  3832. //*************************************************************
  3833. BOOL
  3834. CSecurityPage::UserHasLogonPermission(
  3835. PACL pDacl,
  3836. PSID pSid)
  3837. {
  3838. ASSERT(m_pWorldSid);
  3839. if(!pDacl)
  3840. {
  3841. //DACL == NULL means Everyone - Full Control
  3842. //Let's see if pSid is Everyone's SID
  3843. return EqualSid(pSid, m_pWorldSid);
  3844. }
  3845. ACL_SIZE_INFORMATION asiAclSize;
  3846. DWORD dwBufLength=sizeof(asiAclSize);
  3847. ACCESS_ALLOWED_ACE *pAce;
  3848. DWORD dwAcl_i;
  3849. if (GetAclInformation(pDacl,
  3850. (LPVOID)&asiAclSize,
  3851. (DWORD)dwBufLength,
  3852. (ACL_INFORMATION_CLASS)AclSizeInformation))
  3853. {
  3854. for (dwAcl_i = 0; dwAcl_i < asiAclSize.AceCount; dwAcl_i++)
  3855. {
  3856. if(GetAce( pDacl, dwAcl_i, (LPVOID *)&pAce) &&
  3857. (pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE ||
  3858. pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) )
  3859. {
  3860. if(EqualSid(pSid,PSID(&pAce->SidStart)) &&
  3861. pAce->Mask & WINSTATION_LOGON)
  3862. {
  3863. //Denied ACEs always go first
  3864. if(pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
  3865. {
  3866. return FALSE;
  3867. }
  3868. else
  3869. {
  3870. return TRUE;
  3871. }
  3872. }
  3873. }
  3874. }
  3875. }
  3876. return FALSE;
  3877. }
  3878. //*************************************************************
  3879. //
  3880. // CSecurityPage::UserHasLogonPermission()
  3881. //
  3882. // Purpose: Checks if a user represented by a pSid has explicit
  3883. // Logon permission
  3884. //
  3885. // Parameters: PSECURITY_DESCRIPTOR pSecurityDescriptor -
  3886. // SD to search for user
  3887. // PSID pSid - User's SID.
  3888. //
  3889. // Return: TRUE if a user represented by a pSid has explicit
  3890. // Logon permission.
  3891. // FALSE if not, or in case of any error.
  3892. //
  3893. // Comments:
  3894. //
  3895. // History: Date Author Comment
  3896. // 6/19/01 skuzin Created
  3897. //
  3898. //*************************************************************
  3899. BOOL
  3900. CSecurityPage::UserHasLogonPermission(
  3901. PSECURITY_DESCRIPTOR pSecurityDescriptor,
  3902. PSID pSid)
  3903. {
  3904. PACL pDacl;
  3905. BOOL bDaclPresent;
  3906. BOOL bDaclDefaulted;
  3907. if(!GetSecurityDescriptorDacl(pSecurityDescriptor,&bDaclPresent,&pDacl,&bDaclDefaulted))
  3908. {
  3909. return FALSE;
  3910. }
  3911. return UserHasLogonPermission(pDacl, pSid);
  3912. }
  3913. //*************************************************************
  3914. //
  3915. // CSecurityPage::GetUsersWhoAlreadyHasTSLogonRight()
  3916. //
  3917. // Purpose: Creates an array of SIDs of all users, who have
  3918. // SE_REMOTE_INTERACTIVE_LOGON_NAME right.
  3919. //
  3920. // Parameters: OUT PSID *&ppLogonRightSIDs - array of SIDs of users,
  3921. // who have SE_REMOTE_INTERACTIVE_LOGON_NAME right
  3922. // OUT LPDWORD pcLogonRightSIDs - number of entries
  3923. // in ppLogonRightSIDs
  3924. //
  3925. // Return: TRUE if success
  3926. // FALSE in case of any error.
  3927. //
  3928. // Comments:
  3929. //
  3930. // History: Date Author Comment
  3931. // 6/19/01 skuzin Created
  3932. //
  3933. //*************************************************************
  3934. BOOL
  3935. CSecurityPage::GetUsersWhoAlreadyHasTSLogonRight(
  3936. PSID *&ppLogonRightSIDs,
  3937. LPDWORD pcLogonRightSIDs)
  3938. {
  3939. ppLogonRightSIDs = NULL;
  3940. *pcLogonRightSIDs = 0;
  3941. //Open Lsa Policy on a local machine
  3942. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  3943. LSA_UNICODE_STRING ServerString;
  3944. LSA_HANDLE hPolicy = NULL;
  3945. NTSTATUS Status;
  3946. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  3947. ZeroMemory(&ServerString, sizeof(ServerString));
  3948. Status = LsaOpenPolicy(&ServerString, &ObjectAttributes,
  3949. POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES, &hPolicy);
  3950. if(!NT_SUCCESS(Status))
  3951. {
  3952. return FALSE;
  3953. }
  3954. LSA_UNICODE_STRING UserRight;
  3955. PLSA_ENUMERATION_INFORMATION EnumerationBuffer;
  3956. ULONG CountReturned;
  3957. DWORD dwSidBufferSize = 0;
  3958. InitLsaString( &UserRight, T2W(SE_REMOTE_INTERACTIVE_LOGON_NAME));
  3959. Status=LsaEnumerateAccountsWithUserRight(
  3960. hPolicy,
  3961. &UserRight,
  3962. (PVOID *)&EnumerationBuffer,
  3963. &CountReturned);
  3964. if(NT_SUCCESS(Status))
  3965. {
  3966. dwSidBufferSize = CountReturned * sizeof(PSID);
  3967. DWORD i;
  3968. for(i=0; i<CountReturned; i++)
  3969. {
  3970. dwSidBufferSize += GetLengthSid(EnumerationBuffer[i].Sid);
  3971. }
  3972. ppLogonRightSIDs = (PSID *)new BYTE[dwSidBufferSize];
  3973. if(ppLogonRightSIDs)
  3974. {
  3975. DWORD_PTR CurOffset = DWORD_PTR(CountReturned * sizeof(PSID));
  3976. DWORD CurSidLength = 0;
  3977. for(i=0; i<CountReturned; i++)
  3978. {
  3979. ppLogonRightSIDs[i] = PSID( DWORD_PTR(ppLogonRightSIDs) + CurOffset);
  3980. CurSidLength = GetLengthSid(EnumerationBuffer[i].Sid);
  3981. CopySid(CurSidLength, ppLogonRightSIDs[i], EnumerationBuffer[i].Sid);
  3982. CurOffset += CurSidLength;
  3983. }
  3984. *pcLogonRightSIDs = CountReturned;
  3985. }
  3986. else
  3987. {
  3988. Status = STATUS_NO_MEMORY;
  3989. }
  3990. LsaFreeMemory( EnumerationBuffer );
  3991. }
  3992. else
  3993. {
  3994. //Nobody has this right
  3995. if(Status == STATUS_NO_MORE_ENTRIES)
  3996. {
  3997. Status = STATUS_SUCCESS;
  3998. }
  3999. }
  4000. LsaClose(hPolicy);
  4001. return (NT_SUCCESS(Status));
  4002. }
  4003. //*************************************************************
  4004. //
  4005. // CSecurityPage::GrantRightToUser()
  4006. //
  4007. // Purpose: Grants SE_REMOTE_INTERACTIVE_LOGON_NAME
  4008. // right to a user.
  4009. //
  4010. // Parameters: IN PSID pSID - User's SID
  4011. //
  4012. // Return: TRUE if success
  4013. // FALSE in case of any error.
  4014. //
  4015. // Comments:
  4016. //
  4017. // History: Date Author Comment
  4018. // 6/19/01 skuzin Created
  4019. //
  4020. //*************************************************************
  4021. BOOL
  4022. CSecurityPage::GrantRightToUser(
  4023. IN PSID pSID )
  4024. {
  4025. //Open Lsa Policy on a local machine
  4026. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  4027. LSA_UNICODE_STRING ServerString;
  4028. LSA_HANDLE hPolicy = NULL;
  4029. NTSTATUS Status;
  4030. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  4031. ZeroMemory(&ServerString, sizeof(ServerString));
  4032. Status = LsaOpenPolicy(&ServerString, &ObjectAttributes,
  4033. POLICY_LOOKUP_NAMES | POLICY_CREATE_ACCOUNT, &hPolicy);
  4034. if(!NT_SUCCESS(Status))
  4035. {
  4036. return FALSE;
  4037. }
  4038. LSA_UNICODE_STRING UserRight;
  4039. InitLsaString( &UserRight, T2W(SE_REMOTE_INTERACTIVE_LOGON_NAME));
  4040. Status=LsaAddAccountRights( hPolicy, pSID, &UserRight, 1 );
  4041. LsaClose(hPolicy);
  4042. return (NT_SUCCESS(Status));
  4043. }
  4044. //*************************************************************
  4045. //
  4046. // CSecurityPage::RevokeRightFromUser()
  4047. //
  4048. // Purpose: Revokes SE_REMOTE_INTERACTIVE_LOGON_NAME
  4049. // right from a user.
  4050. //
  4051. // Parameters: IN PSID pSID - User's SID
  4052. //
  4053. // Return: TRUE if success
  4054. // FALSE in case of any error.
  4055. //
  4056. // Comments:
  4057. //
  4058. // History: Date Author Comment
  4059. // 6/19/01 skuzin Created
  4060. //
  4061. //*************************************************************
  4062. BOOL
  4063. CSecurityPage::RevokeRightFromUser(
  4064. IN PSID pSID )
  4065. {
  4066. //Open Lsa Policy on a local machine
  4067. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  4068. LSA_UNICODE_STRING ServerString;
  4069. LSA_HANDLE hPolicy = NULL;
  4070. NTSTATUS Status;
  4071. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  4072. ZeroMemory(&ServerString, sizeof(ServerString));
  4073. Status = LsaOpenPolicy(&ServerString, &ObjectAttributes, POLICY_LOOKUP_NAMES, &hPolicy);
  4074. if(!NT_SUCCESS(Status))
  4075. {
  4076. return FALSE;
  4077. }
  4078. LSA_UNICODE_STRING UserRight;
  4079. InitLsaString( &UserRight, T2W(SE_REMOTE_INTERACTIVE_LOGON_NAME));
  4080. Status=LsaRemoveAccountRights(hPolicy, pSID, FALSE, &UserRight, 1);
  4081. LsaClose(hPolicy);
  4082. return (NT_SUCCESS(Status));
  4083. }
  4084. //*************************************************************
  4085. //
  4086. // CSecurityPage::CanRevokeRight()
  4087. //
  4088. // Purpose: Checks out that user represented by pSid does not
  4089. // have Logon permission to any connection,
  4090. // excluding connection referred by pWSName.
  4091. //
  4092. // Parameters: IN PWINSTATIONNAMEW pWSName - connection name.
  4093. // IN PSID pSID - User's SID
  4094. //
  4095. // Return: TRUE if it is safe to take this right from the user
  4096. // FALSE if not (i.e. the user has Logon permission to at
  4097. // least one connection excluding connection referred by
  4098. // pWSName), or in case of any error.
  4099. //
  4100. // Comments:
  4101. //
  4102. // History: Date Author Comment
  4103. // 6/19/01 skuzin Created
  4104. //
  4105. //*************************************************************
  4106. BOOL
  4107. CSecurityPage::CanRevokeRight(
  4108. IN PWINSTATIONNAMEW pWSName,
  4109. IN PSID pSID )
  4110. {
  4111. ICfgComp *pCfgcomp = NULL;
  4112. if( m_pParent == NULL || m_pParent->m_pResNode == NULL ||
  4113. m_pParent->m_pResNode->GetServer( &pCfgcomp ) == 0)
  4114. {
  4115. return FALSE;
  4116. }
  4117. WS *pWs;
  4118. ULONG ulitems = 0;
  4119. ULONG cbSize = 0;
  4120. if( !SUCCEEDED( pCfgcomp->GetWinstationList( &ulitems , &cbSize , &pWs ) ) )
  4121. {
  4122. return FALSE;
  4123. }
  4124. PSECURITY_DESCRIPTOR pSD;
  4125. long lSDsize;
  4126. BOOL bResult = TRUE;
  4127. for( ULONG i = 0 ; i < ulitems ; ++i )
  4128. {
  4129. if( lstrcmpi( pWs[ i ].Name , pWSName ) )
  4130. {
  4131. if( SUCCEEDED( pCfgcomp->GetSecurityDescriptor( pWs[ i ].Name , &lSDsize , &pSD ) ) )
  4132. {
  4133. if(UserHasLogonPermission(pSD,pSID))
  4134. {
  4135. bResult = FALSE;
  4136. LocalFree(pSD);
  4137. break;
  4138. }
  4139. LocalFree(pSD);
  4140. }
  4141. else
  4142. {
  4143. bResult = FALSE;
  4144. break;
  4145. }
  4146. }
  4147. }
  4148. if(bResult)
  4149. {
  4150. //Check also default security descriptor
  4151. if( SUCCEEDED( pCfgcomp->GetDefaultSecurityDescriptor( &lSDsize , &pSD ) ) )
  4152. {
  4153. if(UserHasLogonPermission(pSD,pSID))
  4154. {
  4155. bResult = FALSE;
  4156. }
  4157. LocalFree(pSD);
  4158. }
  4159. else
  4160. {
  4161. bResult = FALSE;
  4162. }
  4163. }
  4164. CoTaskMemFree( pWs );
  4165. return bResult;
  4166. }
  4167. void
  4168. InitLsaString(
  4169. OUT PLSA_UNICODE_STRING LsaString,
  4170. IN LPWSTR String)
  4171. {
  4172. DWORD StringLength;
  4173. if (String == NULL) {
  4174. LsaString->Buffer = NULL;
  4175. LsaString->Length = 0;
  4176. LsaString->MaximumLength = 0;
  4177. return;
  4178. }
  4179. StringLength = wcslen(String);
  4180. LsaString->Buffer = String;
  4181. LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
  4182. LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
  4183. }
  4184. typedef HPROPSHEETPAGE (*CREATEPAGE_PROC) (LPSECURITYINFO);
  4185. //-----------------------------------------------------------------------------
  4186. HPROPSHEETPAGE GetSecurityPropertyPage( CPropsheet *pParent )
  4187. {
  4188. LPVOID *pvFunction = &g_aAclFunctions[ ACLUI_CREATE_PAGE ].lpfnFunction;
  4189. if( *pvFunction == NULL )
  4190. {
  4191. g_aAclFunctions[ ACLUI_CREATE_PAGE ].hInst = LoadLibrary( TEXT("ACLUI.DLL") );
  4192. ASSERT( g_aAclFunctions[ ACLUI_CREATE_PAGE ].hInst != NULL );
  4193. if( g_aAclFunctions[ ACLUI_CREATE_PAGE ].hInst == NULL )
  4194. {
  4195. return NULL;
  4196. }
  4197. *pvFunction = ( LPVOID )GetProcAddress( g_aAclFunctions[ ACLUI_CREATE_PAGE ].hInst , g_aAclFunctions[ ACLUI_CREATE_PAGE ].pcstrFunctionName );
  4198. ASSERT( *pvFunction != NULL );
  4199. if( *pvFunction == NULL )
  4200. {
  4201. return NULL;
  4202. }
  4203. CComObject< CSecurityPage > *psecinfo = NULL;
  4204. HRESULT hRes = CComObject< CSecurityPage >::CreateInstance( &psecinfo );
  4205. if( SUCCEEDED( hRes ) )
  4206. {
  4207. // InitStrings();
  4208. psecinfo->SetParent( pParent );
  4209. return ( ( CREATEPAGE_PROC )*pvFunction )( psecinfo );
  4210. }
  4211. }
  4212. return NULL;
  4213. }
  4214. //-----------------------------------------------------------------------------
  4215. // Error messag boxes
  4216. //
  4217. void ErrMessage( HWND hwndOwner , INT_PTR iResourceID )
  4218. {
  4219. xxxErrMessage( hwndOwner , iResourceID , IDS_ERROR_TITLE , MB_OK | MB_ICONERROR );
  4220. }
  4221. //-----------------------------------------------------------------------------
  4222. void TscAccessDeniedMsg( HWND hwnd )
  4223. {
  4224. xxxErrMessage( hwnd , IDS_TSCACCESSDENIED , IDS_TSCERRTITLE , MB_OK | MB_ICONERROR );
  4225. }
  4226. //-----------------------------------------------------------------------------
  4227. void TscGeneralErrMsg( HWND hwnd )
  4228. {
  4229. xxxErrMessage( hwnd , IDS_TSCERRGENERAL , IDS_TSCERRTITLE , MB_OK | MB_ICONERROR );
  4230. }
  4231. //-----------------------------------------------------------------------------
  4232. void xxxErrMessage( HWND hwnd , INT_PTR nResMessageId , INT_PTR nResTitleId , UINT nFlags )
  4233. {
  4234. TCHAR tchErrMsg[ 256 ];
  4235. TCHAR tchErrTitle[ 80 ];
  4236. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , ( UINT )nResMessageId , tchErrMsg , SIZE_OF_BUFFER( tchErrMsg ) ) );
  4237. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , ( UINT )nResTitleId , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) ) );
  4238. if( hwnd == NULL )
  4239. {
  4240. nFlags |= MB_TASKMODAL;
  4241. }
  4242. MessageBox( hwnd , tchErrMsg , tchErrTitle , nFlags ) ; //MB_OK|MB_ICONERROR );
  4243. }
  4244. //-----------------------------------------------------------------------------
  4245. void ReportStatusError( HWND hwnd , DWORD dwStatus )
  4246. {
  4247. LPTSTR pBuffer = NULL;
  4248. TCHAR tchTitle[ 80 ];
  4249. TCHAR tchBuffer[ 256 ];
  4250. TCHAR tchErr[ 256 ];
  4251. if( dwStatus != 0 )
  4252. {
  4253. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_TSCERRTITLE , tchTitle , SIZE_OF_BUFFER( tchTitle ) ) );
  4254. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_REPORTERROR , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) ) );
  4255. FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
  4256. FORMAT_MESSAGE_FROM_SYSTEM,
  4257. NULL, //ignored
  4258. dwStatus , //message ID
  4259. MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), //message language
  4260. (LPTSTR)&pBuffer, //address of buffer pointer
  4261. 0, //minimum buffer size
  4262. NULL); //no other arguments
  4263. wsprintf( tchErr , tchBuffer , pBuffer );
  4264. ::MessageBox( hwnd , tchErr , tchTitle , MB_OK | MB_ICONERROR );
  4265. if( pBuffer != NULL )
  4266. {
  4267. LocalFree( pBuffer );
  4268. }
  4269. }
  4270. }
  4271. //=------------------------------------------------------------------------------------------------
  4272. // xxxLegacDenyCleanup -- checked for the old LOGOFF bit
  4273. //=------------------------------------------------------------------------------------------------
  4274. DWORD xxxLegacyLogoffCleanup( PSECURITY_DESCRIPTOR *ppSD , PBOOL pfDaclChanged )
  4275. {
  4276. ACL_SIZE_INFORMATION asi;
  4277. BOOL bDaclPresent;
  4278. BOOL bDaclDefaulted;
  4279. PACL pDacl = NULL;
  4280. SECURITY_DESCRIPTOR_CONTROL sdc;
  4281. DWORD dwREV;
  4282. SECURITY_DESCRIPTOR absSD;
  4283. BOOL bSaclPresent;
  4284. BOOL bSaclDefaulted;
  4285. BOOL bOwnerDefaulted;
  4286. PSID psidOwner = NULL;
  4287. PVOID pAce = NULL;
  4288. PACL pSacl = NULL;
  4289. PSECURITY_DESCRIPTOR pOldSD = NULL;
  4290. DWORD dwStatus = ERROR_SUCCESS;
  4291. ZeroMemory( &asi , sizeof( ACL_SIZE_INFORMATION ) );
  4292. if( !GetSecurityDescriptorDacl( *ppSD ,
  4293. &bDaclPresent ,
  4294. &pDacl,
  4295. &bDaclDefaulted ) )
  4296. {
  4297. dwStatus = GetLastError();
  4298. DBGMSG( L"xxxLegacyLogoffCleanup@GetSecurityDescriptorDacl returned 0x%x\n" , dwStatus );
  4299. return dwStatus;
  4300. }
  4301. do
  4302. {
  4303. *pfDaclChanged = FALSE;
  4304. if( !GetAclInformation( pDacl , &asi , sizeof( asi ) , AclSizeInformation ) )
  4305. {
  4306. dwStatus = GetLastError( );
  4307. DBGMSG( L"xxxLegacyLogoffCleanup@GetAclInformation returned 0x%x\n" , dwStatus );
  4308. break;
  4309. }
  4310. // killed denied logoff.
  4311. BYTE bAceType;
  4312. for( int i = 0 ; i < ( int )asi.AceCount ; ++i )
  4313. {
  4314. if( !GetAce( pDacl , i , &pAce ) )
  4315. {
  4316. dwStatus = GetLastError( );
  4317. DBGMSG( L"xxxLegacyLogoffCleanup@GetAce returned 0x%x\n" , dwStatus );
  4318. break;
  4319. }
  4320. bAceType = ( ( PACE_HEADER )pAce )->AceType;
  4321. if( bAceType == ACCESS_DENIED_ACE_TYPE || bAceType == ACCESS_ALLOWED_ACE_TYPE )
  4322. {
  4323. // if the denied ace represents a single bit get rid of it
  4324. if( ( ( ACCESS_DENIED_ACE * )pAce )->Mask == WINSTATION_LOGOFF )
  4325. {
  4326. if( DeleteAce( pDacl , i ) )
  4327. {
  4328. // pDacl should have been reallocated to we need to re-obtain the acl info
  4329. GetAclInformation( pDacl , &asi , sizeof( asi ) , AclSizeInformation );
  4330. // reset the loop to point to the first ace
  4331. i=-1;
  4332. *pfDaclChanged = TRUE;
  4333. }
  4334. }
  4335. else if( ( ( ACCESS_DENIED_ACE * )pAce )->Mask & WINSTATION_LOGOFF )
  4336. {
  4337. // if the denied ace is a collection of bits with one as logoff turn the bit off
  4338. ( ( ACCESS_DENIED_ACE * )pAce )->Mask ^= WINSTATION_LOGOFF;
  4339. *pfDaclChanged = TRUE;
  4340. }
  4341. }
  4342. }
  4343. if( dwStatus == ERROR_SUCCESS && *pfDaclChanged )
  4344. {
  4345. //
  4346. // Convert SelfRel to Absolute
  4347. //
  4348. DWORD dwSDLen = 0;
  4349. pOldSD = *ppSD;
  4350. GetSecurityDescriptorControl( *ppSD , &sdc , &dwREV );
  4351. InitializeSecurityDescriptor( &absSD , dwREV );
  4352. SetSecurityDescriptorDacl( &absSD , bDaclPresent , pDacl , bDaclDefaulted );
  4353. GetSecurityDescriptorSacl( *ppSD , &bSaclPresent , &pSacl , &bSaclDefaulted );
  4354. SetSecurityDescriptorSacl( &absSD , bSaclPresent , pSacl , bSaclDefaulted );
  4355. GetSecurityDescriptorOwner( *ppSD , &psidOwner , &bOwnerDefaulted );
  4356. SetSecurityDescriptorOwner( &absSD , psidOwner , FALSE );
  4357. SetSecurityDescriptorGroup( &absSD , psidOwner , FALSE );
  4358. *ppSD = NULL;
  4359. if( !MakeSelfRelativeSD( &absSD , *ppSD , &dwSDLen ) )
  4360. {
  4361. ODS( L"xxxLegacyLogoffCleanup -- MakeSelfRelativeSD failed as expected\n" );
  4362. *ppSD = ( PSECURITY_DESCRIPTOR )LocalAlloc( LMEM_FIXED , dwSDLen );
  4363. if( *ppSD == NULL )
  4364. {
  4365. dwStatus = ERROR_NOT_ENOUGH_MEMORY;
  4366. DBGMSG( L"xxxLegacyLogoffCleanup -- LocalAlloc failed 0x%x\n" , dwStatus );
  4367. break;
  4368. }
  4369. if( !MakeSelfRelativeSD( &absSD , *ppSD , &dwSDLen ) )
  4370. {
  4371. dwStatus = GetLastError( );
  4372. DBGMSG( L"xxxLegacyLogoffCleanup -- MakeSelfRelativeSD failed 0x%x\n" , dwStatus );
  4373. break;
  4374. }
  4375. }
  4376. }
  4377. }while( 0 );
  4378. if( pOldSD != NULL )
  4379. {
  4380. LocalFree( pOldSD );
  4381. }
  4382. return dwStatus;
  4383. }
  4384. //
  4385. INT_PTR APIENTRY
  4386. CustomSecurityDlgProc (
  4387. HWND hDlg,
  4388. UINT uMsg,
  4389. WPARAM wParam,
  4390. LPARAM lParam)
  4391. {
  4392. UNREFERENCED_PARAMETER( hDlg );
  4393. switch (uMsg)
  4394. {
  4395. case WM_INITDIALOG:
  4396. // This may seem that it does nothin, but it casues this function to return TRUE
  4397. // otherwise, you won't get this dialog!
  4398. break;
  4399. case WM_NOTIFY:
  4400. switch (((NMHDR FAR*)lParam)->code)
  4401. {
  4402. case NM_CLICK:
  4403. case NM_RETURN:
  4404. if(wParam == IDC_GP_LINK)
  4405. {
  4406. ShellExecute(NULL,TEXT("open"),TEXT("gpedit.msc"),NULL,NULL,SW_SHOW);
  4407. break;
  4408. }
  4409. else
  4410. {
  4411. return FALSE;
  4412. }
  4413. default:
  4414. return FALSE;
  4415. }
  4416. break;
  4417. case WM_COMMAND:
  4418. switch(LOWORD(wParam))
  4419. {
  4420. case IDOK:
  4421. case IDCANCEL:
  4422. EndDialog(hDlg,0);
  4423. break;
  4424. default:
  4425. return FALSE;
  4426. }
  4427. default:
  4428. return FALSE;
  4429. }
  4430. return TRUE;
  4431. }