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.

4277 lines
114 KiB

  1. //---------------------------------------------------------------------------
  2. // Copyright (c) 1998, Microsoft Corporation
  3. // All Rights Reserved
  4. // Information Contained Herein Is Proprietary and Confidential
  5. //
  6. // Author: alhen
  7. //---------------------------------------------------------------------------
  8. #include "stdafx.h"
  9. #include "resource.h"
  10. #include "tsusrsht.h"
  11. //#include <dsgetdc.h>
  12. #include <icanon.h>
  13. #include <shlwapi.h>
  14. // extern BOOL g_bPagesHaveBeenInvoked;
  15. /*NTSTATUS GetDomainName( PWCHAR ServerNamePtr, // name of server to get domain of
  16. LPTSTR DomainNamePtr // alloc and set ptr (free with NetApiBufferFree)
  17. );
  18. */
  19. WNDPROC CTimeOutDlg::m_pfWndproc = 0;
  20. //-------------------------------------------------------------------------------
  21. /*
  22. static TOKTABLE tokday[ 4 ] = {
  23. { NULL , IDS_D },
  24. { NULL , IDS_DAY },
  25. { NULL , IDS_DAYS },
  26. { NULL , ( DWORD )-1 }
  27. };
  28. static TOKTABLE tokhour[ 6 ] = {
  29. { NULL , IDS_H },
  30. { NULL , IDS_HR },
  31. { NULL , IDS_HRS },
  32. { NULL , IDS_HOUR },
  33. { NULL , IDS_HOURS },
  34. { NULL , ( DWORD )-1 }
  35. };
  36. static TOKTABLE tokmin[ 5 ] = {
  37. { NULL , IDS_M },
  38. { NULL , IDS_MIN },
  39. { NULL , IDS_MINUTE },
  40. { NULL , IDS_MINUTES },
  41. { NULL , ( DWORD )-1 }
  42. };
  43. */
  44. TCHAR * GetNextToken( TCHAR *pszString , TCHAR *tchToken );
  45. void ErrorMessage1( HWND hParent , DWORD dwStatus );
  46. void ErrorMessage2( HWND hParent , DWORD dwStatus );
  47. void xxErrorMessage( HWND hParent , DWORD dwStatus , UINT );
  48. //-------------------------------------------------------------------------------
  49. // CTUSerDlg::ctor
  50. //-------------------------------------------------------------------------------
  51. CTSUserSheet::CTSUserSheet( )
  52. {
  53. m_pstrMachinename = NULL;
  54. m_pstrUsername = NULL;
  55. m_cref = 0;
  56. m_bIsConfigLoaded = FALSE;
  57. m_szRemoteServerName[0] = 0;
  58. m_pUserSid = NULL;
  59. for( int tt = 0 ; tt < NUM_OF_PAGES ; ++tt )
  60. {
  61. m_pDlg[ tt ] = NULL;
  62. }
  63. }
  64. //-------------------------------------------------------------------------------
  65. // CTUSerDlg::dtor
  66. //-------------------------------------------------------------------------------
  67. CTSUserSheet::~CTSUserSheet()
  68. {
  69. if( m_pstrMachinename != NULL )
  70. {
  71. delete[] m_pstrMachinename;
  72. }
  73. if( m_pstrUsername != NULL )
  74. {
  75. delete[] m_pstrUsername;
  76. }
  77. for( int tt = 0 ; tt < NUM_OF_PAGES ; ++tt )
  78. {
  79. if( m_pDlg[ tt ] != NULL )
  80. {
  81. delete m_pDlg[ tt ];
  82. }
  83. }
  84. if( m_pUserSid != NULL )
  85. {
  86. delete[] m_pUserSid;
  87. }
  88. ODS( TEXT("Main object released!\n") );
  89. }
  90. //ptstrMachineName will be allocated by this routine so it is up
  91. //to the calling function to delete it. FALSE will be returned
  92. //if the parameter is not allocated
  93. BOOL CTSUserSheet::GetServer(PWSTR *ptstrMachineName)
  94. {
  95. if (m_pstrMachinename)
  96. {
  97. DWORD dwLen = wcslen(m_pstrMachinename);
  98. *ptstrMachineName = new WCHAR[dwLen + 1];
  99. if (*ptstrMachineName)
  100. {
  101. wcscpy(*ptstrMachineName, m_pstrMachinename);
  102. return TRUE;
  103. }
  104. }
  105. return FALSE;
  106. }
  107. //-------------------------------------------------------------------------------
  108. // SetServerAndUser
  109. //-------------------------------------------------------------------------------
  110. BOOL CTSUserSheet::SetServerAndUser( LPWSTR pwstrMachineName , LPWSTR pwstrUserName )
  111. {
  112. if( pwstrMachineName != NULL && pwstrUserName != NULL )
  113. {
  114. KdPrint( ("TSUSEREX : SystemName %ws UserName %ws\n",pwstrMachineName,pwstrUserName) );
  115. DWORD dwLen = wcslen( pwstrMachineName );
  116. m_pstrMachinename = ( LPTSTR )new TCHAR [ dwLen + 1 ];
  117. if( m_pstrMachinename != NULL )
  118. {
  119. COPYWCHAR2TCHAR( m_pstrMachinename , pwstrMachineName );
  120. }
  121. dwLen = wcslen( pwstrUserName );
  122. m_pstrUsername = ( LPTSTR )new TCHAR[ dwLen + 1 ];
  123. if( m_pstrUsername != NULL )
  124. {
  125. COPYWCHAR2TCHAR( m_pstrUsername , pwstrUserName );
  126. }
  127. return TRUE;
  128. }
  129. return FALSE;
  130. }
  131. //-------------------------------------------------------------------------------
  132. // AddPagesToPropSheet
  133. //-------------------------------------------------------------------------------
  134. HRESULT CTSUserSheet::AddPagesToPropSheet( LPPROPERTYSHEETCALLBACK pProvider )
  135. {
  136. PROPSHEETPAGE psp;
  137. //
  138. // List of objects goes here
  139. //
  140. m_pDlg[0] = new CEnviroDlg( this );
  141. m_pDlg[1] = new CTimeOutDlg( this );
  142. m_pDlg[2] = new CShadowDlg( this );
  143. m_pDlg[3] = new CProfileDlg( this );
  144. //
  145. // Let each object initialize there own propsheet
  146. //
  147. for( int idx = 0; idx < NUM_OF_PAGES; ++idx )
  148. {
  149. if( m_pDlg[ idx ] != NULL )
  150. {
  151. if( !m_pDlg[ idx ]->GetPropertySheetPage( psp ) )
  152. {
  153. continue;
  154. }
  155. if( FAILED( pProvider->AddPage( CreatePropertySheetPage( &psp ) ) ) )
  156. {
  157. return E_FAIL;
  158. }
  159. }
  160. }
  161. return S_OK;
  162. }
  163. //-------------------------------------------------------------------------------
  164. // AddPagesToDSAPropSheet
  165. //-------------------------------------------------------------------------------
  166. HRESULT CTSUserSheet::AddPagesToDSAPropSheet( LPFNADDPROPSHEETPAGE lpfnAddPage , LPARAM lp )
  167. {
  168. PROPSHEETPAGE psp;
  169. //
  170. // List of objects goes here
  171. //
  172. m_pDlg[0] = new CEnviroDlg( this );
  173. m_pDlg[1] = new CTimeOutDlg( this );
  174. m_pDlg[2] = new CShadowDlg( this );
  175. m_pDlg[3] = new CProfileDlg( this );
  176. //
  177. // Let each object initialize there own propsheet
  178. //
  179. for( int idx = 0; idx < NUM_OF_PAGES; ++idx )
  180. {
  181. if( m_pDlg[ idx ] != NULL )
  182. {
  183. if( !m_pDlg[ idx ]->GetPropertySheetPage( psp ) )
  184. {
  185. continue;
  186. }
  187. lpfnAddPage( CreatePropertySheetPage( &psp ) , lp );
  188. }
  189. }
  190. return S_OK;
  191. }
  192. //-------------------------------------------------------------------------------
  193. // SetUserConfig
  194. //-------------------------------------------------------------------------------
  195. BOOL CTSUserSheet::SetUserConfig( USERCONFIG& uc , PDWORD pdwStatus )
  196. {
  197. ASSERT_( pdwStatus != NULL );
  198. if( IsBadReadPtr( &uc , sizeof( USERCONFIG ) ) )
  199. {
  200. return FALSE;
  201. }
  202. //
  203. //
  204. // mov esi,dword ptr [uc]
  205. // mov edi,dword ptr [this]
  206. // add edi,1Ch
  207. // mov ecx,27Ah
  208. // rep movs dword ptr es:[edi],dword ptr [esi]
  209. //
  210. // is the codegen for struct = struct
  211. //
  212. m_userconfig = uc;
  213. #if BETA_3
  214. TCHAR tchServerName[ MAX_PATH ];
  215. if( m_bDC )
  216. {
  217. ODS( L"TSUSEREX - Saving settings on remote or local-dc system\n" );
  218. lstrcpy( tchServerName , m_szRemoteServerName );
  219. }
  220. else
  221. {
  222. lstrcpy( tchServerName , m_pstrMachinename );
  223. }
  224. #endif // BETA_3
  225. if( ( *pdwStatus = RegUserConfigSet( m_pstrMachinename , m_pstrUsername , &m_userconfig , sizeof( USERCONFIG ) ) ) == ERROR_SUCCESS )
  226. {
  227. return TRUE;
  228. }
  229. return FALSE;
  230. }
  231. //-------------------------------------------------------------------------------
  232. // GetCurrentUserConfig
  233. //-------------------------------------------------------------------------------
  234. USERCONFIG& CTSUserSheet::GetCurrentUserConfig( PDWORD pdwStatus )
  235. {
  236. *pdwStatus = ERROR_SUCCESS;
  237. if( !m_bIsConfigLoaded )
  238. {
  239. m_bIsConfigLoaded = GetUserConfig( pdwStatus );
  240. }
  241. // ASSERT_( m_bIsConfigLoaded );
  242. return m_userconfig;
  243. }
  244. //-------------------------------------------------------------------------------
  245. // GetUserConfig
  246. //-------------------------------------------------------------------------------
  247. BOOL CTSUserSheet::GetUserConfig( PDWORD pdwStatus )
  248. {
  249. ASSERT_( pdwStatus != NULL );
  250. //
  251. // This should only be called once
  252. //
  253. DWORD cbWritten = 0;
  254. #if BETA_3
  255. PSERVER_INFO_101 psinfo;
  256. // check to see if we're trying to administer a local system that happens to be a dc
  257. *pdwStatus = NetServerGetInfo( NULL , 101 , ( LPBYTE * )&psinfo );
  258. KdPrint( ("TSUSEREX : NetServerGetInfo returned 0x%x\n",*pdwStatus ) );
  259. KdPrint( ("TSUSEREX : LastError was 0x%x\n",GetLastError( ) ) );
  260. if( *pdwStatus == NERR_Success )
  261. {
  262. // used to avoid access violation
  263. if( psinfo != NULL )
  264. {
  265. KdPrint( ("TSUSEREX : PSERVER_INFO_101 returned 0x%x\n",psinfo->sv101_type ) );
  266. m_bDC = ( BOOL )( psinfo->sv101_type & ( SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_BAKCTRL ) );
  267. if( m_bDC )
  268. {
  269. // get the domaincontroller name of the remote machine
  270. DOMAIN_CONTROLLER_INFO *pdinfo;
  271. // m_pstrMachinename is really the domain name. This was obtain
  272. // from LookUpAccountSid in interfaces.cpp
  273. *pdwStatus = DsGetDcName( NULL , m_pstrMachinename , NULL , NULL , DS_PDC_REQUIRED , &pdinfo );
  274. KdPrint( ( "TSUSEREX : DsGetDcName: %ws returned 0x%x\n", pdinfo->DomainControllerName , *pdwStatus ) );
  275. if( *pdwStatus == NO_ERROR )
  276. {
  277. lstrcpy( m_szRemoteServerName , pdinfo->DomainControllerName );
  278. NetApiBufferFree( pdinfo );
  279. }
  280. else
  281. {
  282. m_szRemoteServerName[0] = 0;
  283. }
  284. }
  285. // not documented in the docs but NetServerGetInfo leaves it up to the caller to free up this blob
  286. NetApiBufferFree( psinfo );
  287. }
  288. TCHAR tchServerName[ MAX_PATH ];
  289. if( m_bDC )
  290. {
  291. lstrcpy( tchServerName , m_szRemoteServerName );
  292. }
  293. else
  294. {
  295. lstrcpy( tchServerName , m_pstrMachinename );
  296. }
  297. if( ( *pdwStatus = ( DWORD )RegUserConfigQuery( tchServerName , m_pstrUsername , &m_userconfig , sizeof( USERCONFIG ) , &cbWritten ) ) == ERROR_SUCCESS )
  298. {
  299. return TRUE;
  300. }
  301. }
  302. #endif // BETA_3
  303. if( ( *pdwStatus = ( DWORD )RegUserConfigQuery( m_pstrMachinename , m_pstrUsername , &m_userconfig , sizeof( USERCONFIG ) , &cbWritten ) ) == ERROR_SUCCESS )
  304. {
  305. return TRUE;
  306. }
  307. ODS( L"TSUSEREX: We're getting default properties\n" );
  308. RegDefaultUserConfigQuery( m_pstrMachinename , &m_userconfig , sizeof( USERCONFIG ) , &cbWritten );
  309. return FALSE;
  310. }
  311. void CTSUserSheet::CopyUserSid( PSID psid )
  312. {
  313. if( !IsValidSid( psid ) )
  314. {
  315. ODS( L"TSUSEREX : CTSUserSheet::CopyUserSid invalid arg\n" ) ;
  316. return;
  317. }
  318. m_pUserSid = psid;
  319. }
  320. //----------------------------------------------------------
  321. // This provides reference counting for the dialog boxes
  322. // and destroys the sheet (thus destroying the dialog boxes)
  323. // when the ref count reaches 0
  324. //----------------------------------------------------------
  325. UINT CALLBACK CDialogBase::PageCallback(HWND hDlg, UINT uMsg, LPPROPSHEETPAGE ppsp)
  326. {
  327. if (!ppsp)
  328. return FALSE;
  329. // We need to recover a pointer to the current instance. We can't just use
  330. // "this" because we are in a static function
  331. CDialogBase* pMe = reinterpret_cast<CDialogBase*>(ppsp->lParam);
  332. if (!pMe)
  333. return FALSE;
  334. if (uMsg == 0)
  335. ++(pMe->m_pUSht->m_cref);
  336. if (uMsg == PSPCB_RELEASE)
  337. {
  338. if( --(pMe->m_pUSht->m_cref) == 0 )
  339. delete (pMe->m_pUSht);
  340. }
  341. return TRUE;
  342. }
  343. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  344. //-------------------------------------------------------------------------------
  345. // Base class initi
  346. //-------------------------------------------------------------------------------
  347. CDialogBase::CDialogBase( )
  348. {
  349. m_hWnd = NULL;
  350. }
  351. //-------------------------------------------------------------------------------
  352. // Base initialization
  353. //-------------------------------------------------------------------------------
  354. BOOL CDialogBase::OnInitDialog( HWND hwnd , WPARAM , LPARAM )
  355. {
  356. m_hWnd = hwnd;
  357. return FALSE;
  358. }
  359. //-------------------------------------------------------------------------------
  360. // OnNotify - base class method
  361. //-------------------------------------------------------------------------------
  362. BOOL CDialogBase::OnNotify( int , LPNMHDR pnmh , HWND hDlg )
  363. {
  364. if( pnmh->code == PSN_APPLY )
  365. {
  366. if( !m_bPersisted )
  367. {
  368. m_bPersisted = PersistSettings( hDlg );
  369. }
  370. }
  371. else if( pnmh->code == PSN_KILLACTIVE )
  372. {
  373. if( !m_bPersisted )
  374. {
  375. if( !IsValidSettings( hDlg ) )
  376. {
  377. SetWindowLongPtr( hDlg , DWLP_MSGRESULT , PSNRET_INVALID_NOCHANGEPAGE );
  378. return TRUE;
  379. }
  380. }
  381. }
  382. return FALSE;
  383. }
  384. //-------------------------------------------------------------------------------
  385. // OnCOntextMenu -- base class operation
  386. //-------------------------------------------------------------------------------
  387. BOOL CDialogBase::OnContextMenu( HWND hwnd , POINT& )
  388. {
  389. TCHAR tchHelpFile[ MAX_PATH ];
  390. if( m_hWnd == GetParent( hwnd ) )
  391. {
  392. //
  393. // Make sure its not a dummy window
  394. //
  395. if( GetDlgCtrlID( hwnd ) <= ( int )-1 )
  396. {
  397. return FALSE;
  398. }
  399. DWORD rgdw[ 2 ];
  400. rgdw[ 0 ] = GetDlgCtrlID( hwnd );
  401. rgdw[ 1 ] = GetWindowContextHelpId( hwnd );
  402. LoadString( _Module.GetModuleInstance( ) , IDS_HELPFILE , tchHelpFile , sizeof( tchHelpFile ) / sizeof( TCHAR ) );
  403. WinHelp( hwnd , tchHelpFile , HELP_CONTEXTMENU , (ULONG_PTR)&rgdw );
  404. }
  405. return TRUE;
  406. }
  407. //-------------------------------------------------------------------------------
  408. // Each control has a helpid assign to them. Some controls share the same topic
  409. // check for these.
  410. //-------------------------------------------------------------------------------
  411. BOOL CDialogBase::OnHelp( HWND hwnd , LPHELPINFO lphi )
  412. {
  413. TCHAR tchHelpFile[ MAX_PATH ];
  414. //
  415. // For the information to winhelp api
  416. //
  417. if( IsBadReadPtr( lphi , sizeof( HELPINFO ) ) )
  418. {
  419. return FALSE;
  420. }
  421. if( (short)lphi->iCtrlId <= -1 )
  422. {
  423. return FALSE;
  424. }
  425. LoadString( _Module.GetModuleInstance( ) , IDS_HELPFILE , tchHelpFile , sizeof( tchHelpFile ) / sizeof( TCHAR ) );
  426. WinHelp( hwnd , tchHelpFile , HELP_CONTEXTPOPUP , lphi->dwContextId );
  427. return TRUE;
  428. }
  429. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  430. //-------------------------------------------------------------------------------
  431. // CEnviroDlg::ctor
  432. //-------------------------------------------------------------------------------
  433. CEnviroDlg::CEnviroDlg( CTSUserSheet *pUSht )
  434. {
  435. m_pUSht = pUSht;
  436. }
  437. //-------------------------------------------------------------------------------
  438. // InitDialog for ProfileDlg
  439. //-------------------------------------------------------------------------------
  440. BOOL CEnviroDlg::OnInitDialog( HWND hwnd , WPARAM wp , LPARAM lp )
  441. {
  442. DWORD dwStatus;
  443. if( IsBadReadPtr( m_pUSht ,sizeof( CTSUserSheet ) ) )
  444. {
  445. return FALSE;
  446. }
  447. USERCONFIG uc;
  448. uc = m_pUSht->GetCurrentUserConfig( &dwStatus );
  449. // This means any true problems from obtaining user info from the sam
  450. // will disable this dialog
  451. if( dwStatus != ERROR_FILE_NOT_FOUND && dwStatus != ERROR_SUCCESS )
  452. {
  453. INT nId[ ] = {
  454. IDC_CHECK_USEDEFAULT,
  455. IDC_EDIT_CMDLINE,
  456. IDC_EDIT_WDIR,
  457. IDC_CHECK_CCDL,
  458. IDC_CHECK_CCPL,
  459. IDC_CHECK_DMCP,
  460. -1
  461. };
  462. for( int idx = 0; nId[ idx ] != -1 ; ++idx )
  463. {
  464. EnableWindow( GetDlgItem( hwnd , nId[ idx ] ) , FALSE );
  465. }
  466. ErrorMessage1( hwnd , dwStatus );
  467. return FALSE;
  468. }
  469. SendMessage( GetDlgItem( hwnd , IDC_EDIT_CMDLINE ) , EM_SETLIMITTEXT , ( WPARAM )DIRECTORY_LENGTH , 0 );
  470. SendMessage( GetDlgItem( hwnd , IDC_EDIT_WDIR ) , EM_SETLIMITTEXT , ( WPARAM )DIRECTORY_LENGTH , 0 );
  471. //
  472. // Set controls to default status
  473. //
  474. SendMessage( GetDlgItem( hwnd , IDC_CHECK_USEDEFAULT ) , BM_SETCHECK , !( WPARAM )uc.fInheritInitialProgram , 0 );
  475. SetWindowText( GetDlgItem( hwnd , IDC_EDIT_WDIR ) , uc.WorkDirectory );
  476. SetWindowText( GetDlgItem( hwnd , IDC_EDIT_CMDLINE ) , uc.InitialProgram ) ;
  477. EnableWindow( GetDlgItem( hwnd , IDC_EDIT_WDIR ) , !uc.fInheritInitialProgram );
  478. EnableWindow( GetDlgItem( hwnd , IDC_EDIT_CMDLINE ) , !uc.fInheritInitialProgram );
  479. EnableWindow( GetDlgItem( hwnd , IDC_STATIC_WD ) , !uc.fInheritInitialProgram );
  480. EnableWindow( GetDlgItem( hwnd , IDC_STATIC_CMD ) , !uc.fInheritInitialProgram );
  481. //
  482. // The controls are initially enabled - - resetting them is done
  483. // via WM_COMMAND
  484. //
  485. SendMessage( GetDlgItem( hwnd , IDC_CHECK_CCDL ) , BM_SETCHECK , ( WPARAM )uc.fAutoClientDrives , 0 );
  486. SendMessage( GetDlgItem( hwnd , IDC_CHECK_CCPL ) , BM_SETCHECK , ( WPARAM )uc.fAutoClientLpts , 0 );
  487. SendMessage( GetDlgItem( hwnd , IDC_CHECK_DMCP ) , BM_SETCHECK , ( WPARAM )uc.fForceClientLptDef , 0 );
  488. m_bPersisted = TRUE;
  489. return CDialogBase::OnInitDialog( hwnd , wp , lp );
  490. }
  491. //-------------------------------------------------------------------------------
  492. // Environment Dialog Page
  493. // -- static methods lacks this ptr
  494. //-------------------------------------------------------------------------------
  495. INT_PTR CALLBACK CEnviroDlg::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  496. {
  497. CEnviroDlg *pDlg;
  498. if( msg == WM_INITDIALOG )
  499. {
  500. CEnviroDlg *pDlg = ( CEnviroDlg * )( ( PROPSHEETPAGE *)lp )->lParam ;
  501. //
  502. // Don't use a static pointer here
  503. // There will be concurrency issues
  504. //
  505. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  506. if( !IsBadReadPtr( pDlg , sizeof( CEnviroDlg ) ) )
  507. {
  508. pDlg->OnInitDialog( hwnd , wp , lp );
  509. }
  510. return 0;
  511. }
  512. else
  513. {
  514. pDlg = ( CEnviroDlg * )GetWindowLongPtr( hwnd , DWLP_USER );
  515. if( IsBadReadPtr( pDlg , sizeof( CEnviroDlg ) ) )
  516. {
  517. return FALSE;
  518. }
  519. }
  520. switch( msg )
  521. {
  522. case WM_NCDESTROY:
  523. pDlg->OnDestroy( );
  524. break;
  525. case WM_COMMAND:
  526. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  527. break;
  528. case WM_NOTIFY:
  529. pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  530. break;
  531. case WM_HELP:
  532. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  533. break;
  534. case WM_RBUTTONUP:
  535. {
  536. POINT pt;
  537. pt.x = LOWORD( lp );
  538. pt.y = HIWORD( lp );
  539. HWND hChild = ChildWindowFromPoint( hwnd , pt );
  540. ClientToScreen( hwnd , &pt );
  541. pDlg->OnContextMenu( hChild , pt );
  542. }
  543. break;
  544. case WM_CONTEXTMENU:
  545. {
  546. POINT pt;
  547. pt.x = LOWORD( lp );
  548. pt.y = HIWORD( lp );
  549. pDlg->OnContextMenu( ( HWND )wp , pt );
  550. }
  551. }
  552. return 0;
  553. }
  554. //-------------------------------------------------------------------------------
  555. // Basic control notification handler
  556. //-------------------------------------------------------------------------------
  557. void CEnviroDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtl )
  558. {
  559. switch( wNotifyCode )
  560. {
  561. case BN_CLICKED:
  562. if( wID == IDC_CHECK_USEDEFAULT )
  563. {
  564. //
  565. // Remember if its checked we want to disable the options
  566. //
  567. HWND hwnd = GetParent( hwndCtl );
  568. BOOL bChecked = SendMessage( hwndCtl , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  569. EnableWindow( GetDlgItem( hwnd , IDC_EDIT_WDIR ) , bChecked );
  570. EnableWindow( GetDlgItem( hwnd , IDC_EDIT_CMDLINE ) , bChecked );
  571. EnableWindow( GetDlgItem( hwnd , IDC_STATIC_WD ) , bChecked );
  572. EnableWindow( GetDlgItem( hwnd , IDC_STATIC_CMD ) , bChecked );
  573. } // FALL THROUGH !!!!
  574. case EN_CHANGE:
  575. m_bPersisted = FALSE;
  576. break;
  577. case ALN_APPLY:
  578. //This is being removed for consinstency with the rest of MMC dialogs, even though it would
  579. //make more sense to the user for Cancel to be disabled after applying the changes, since
  580. //cancellation is not a real option at that point.
  581. //SendMessage( GetParent( hwndCtl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  582. break;
  583. }
  584. if( !m_bPersisted )
  585. {
  586. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  587. }
  588. }
  589. //-------------------------------------------------------------------------------
  590. // OnDestroy
  591. //-------------------------------------------------------------------------------
  592. BOOL CEnviroDlg::OnDestroy( )
  593. {
  594. return CDialogBase::OnDestroy( );
  595. }
  596. //-------------------------------------------------------------------------------
  597. // GetPropertySheetPage - each dialog object should be responsible for its own data
  598. //-------------------------------------------------------------------------------
  599. BOOL CEnviroDlg::GetPropertySheetPage( PROPSHEETPAGE &psp)
  600. {
  601. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  602. psp.dwSize = sizeof( PROPSHEETPAGE );
  603. psp.dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
  604. psp.hInstance = _Module.GetModuleInstance( );
  605. psp.pszTemplate = MAKEINTRESOURCE( IDD_PAGE_ENVIRO );
  606. psp.lParam = (LPARAM)this;
  607. psp.pfnCallback = CDialogBase::PageCallback;
  608. psp.pfnDlgProc = CEnviroDlg::DlgProc;
  609. return TRUE;
  610. }
  611. //-------------------------------------------------------------------------------
  612. // PersistSettings
  613. //-------------------------------------------------------------------------------
  614. BOOL CEnviroDlg::PersistSettings( HWND hDlg )
  615. {
  616. DWORD dwStatus;
  617. if( IsBadReadPtr( m_pUSht , sizeof( CTSUserSheet ) ) )
  618. {
  619. return FALSE;
  620. }
  621. USERCONFIG uc;
  622. TCHAR tchBuffer[ DIRECTORY_LENGTH + 1 ];
  623. uc = m_pUSht->GetCurrentUserConfig( &dwStatus );
  624. //
  625. // if use default is checked -- lets flag it and move on to client devices
  626. //
  627. //
  628. // if the chkbx is unchecked we inherit from client side settings
  629. //
  630. uc.fInheritInitialProgram = SendMessage( GetDlgItem( hDlg , IDC_CHECK_USEDEFAULT ) , BM_GETCHECK ,
  631. 0 , 0 ) == BST_CHECKED ? FALSE : TRUE;
  632. if( !uc.fInheritInitialProgram )
  633. {
  634. //
  635. // Read buffer and commit to USERCONFIG buffer
  636. //
  637. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_WDIR ) , &tchBuffer[ 0 ] , sizeof( tchBuffer ) / sizeof( TCHAR ) );
  638. lstrcpy( uc.WorkDirectory , tchBuffer );
  639. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_CMDLINE ) , &tchBuffer[ 0 ] , sizeof( tchBuffer ) / sizeof( TCHAR ) );
  640. lstrcpy( uc.InitialProgram , tchBuffer );
  641. }
  642. else
  643. {
  644. lstrcpy(uc.WorkDirectory, L"");
  645. lstrcpy(uc.InitialProgram, L"");
  646. }
  647. uc.fAutoClientDrives = SendMessage( GetDlgItem( hDlg , IDC_CHECK_CCDL ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  648. uc.fAutoClientLpts = SendMessage( GetDlgItem( hDlg , IDC_CHECK_CCPL ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  649. uc.fForceClientLptDef = SendMessage( GetDlgItem( hDlg , IDC_CHECK_DMCP ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  650. if( !m_pUSht->SetUserConfig( uc , &dwStatus ) )
  651. {
  652. ErrorMessage2( hDlg , dwStatus );
  653. return TRUE;
  654. }
  655. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  656. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  657. return TRUE;
  658. }
  659. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  660. DWORD rgdwTime[] = { 0 , 1 , 5 , 10 , 15 , 30 , 60 , 120 , 180 , 1440 , 2880 , ( DWORD )-1 };
  661. //-------------------------------------------------------------------------------
  662. // CTimeOutDlg::ctor
  663. //-------------------------------------------------------------------------------
  664. CTimeOutDlg::CTimeOutDlg( CTSUserSheet *pUSht )
  665. {
  666. m_pUSht = pUSht;
  667. ZeroMemory( &m_cbxst , sizeof( CBXSTATE ) * 3 );
  668. m_wAction = ( WORD)-1;
  669. m_wCon = ( WORD )-1;
  670. ZeroMemory( &m_tokday , sizeof( TOKTABLE ) * 4 );
  671. ZeroMemory( &m_tokhour , sizeof( TOKTABLE ) * 6 );
  672. ZeroMemory( &m_tokmin , sizeof( TOKTABLE ) * 5 );
  673. }
  674. //-------------------------------------------------------------------------------
  675. void CTimeOutDlg::InitTokTables( )
  676. {
  677. TOKTABLE tday[4] = { { NULL , IDS_D },
  678. { NULL , IDS_DAY },
  679. { NULL , IDS_DAYS },
  680. { NULL , ( DWORD )-1 }
  681. };
  682. TOKTABLE thour[ 6 ] = {
  683. { NULL , IDS_H },
  684. { NULL , IDS_HR },
  685. { NULL , IDS_HRS },
  686. { NULL , IDS_HOUR },
  687. { NULL , IDS_HOURS },
  688. { NULL , ( DWORD )-1 }
  689. };
  690. TOKTABLE tmin[ 5 ] = {
  691. { NULL , IDS_M },
  692. { NULL , IDS_MIN },
  693. { NULL , IDS_MINUTE },
  694. { NULL , IDS_MINUTES },
  695. { NULL , ( DWORD )-1 }
  696. };
  697. CopyMemory( &m_tokday[0] , &tday[0] , sizeof( TOKTABLE ) * 4 );
  698. CopyMemory( &m_tokhour[0] , &thour[0] , sizeof( TOKTABLE ) * 6 );
  699. CopyMemory( &m_tokmin[0] , &tmin[0] , sizeof( TOKTABLE ) * 5 );
  700. }
  701. //-------------------------------------------------------------------------------
  702. // InitDialog for TimeOutDlg
  703. //-------------------------------------------------------------------------------
  704. BOOL CTimeOutDlg::OnInitDialog( HWND hwnd , WPARAM wp , LPARAM lp )
  705. {
  706. TCHAR tchBuffer[ 80 ];
  707. DWORD dwStatus;
  708. USERCONFIG uc;
  709. if( IsBadReadPtr( m_pUSht , sizeof( CTSUserSheet ) ) )
  710. {
  711. return FALSE;
  712. }
  713. InitTokTables( );
  714. uc = m_pUSht->GetCurrentUserConfig( &dwStatus );
  715. if( dwStatus != ERROR_FILE_NOT_FOUND && dwStatus != ERROR_SUCCESS )
  716. {
  717. INT nId[ ] = {
  718. IDC_COMBO_CONNECT,
  719. IDC_COMBO_DISCON,
  720. IDC_COMBO_IDLE,
  721. IDC_RADIO_RESET,
  722. IDC_RADIO_DISCON,
  723. IDC_RADIO_PREVCLIENT,
  724. IDC_RADIO_ANYCLIENT,
  725. -1
  726. };
  727. for( int idx = 0; nId[ idx ] != -1 ; ++idx )
  728. {
  729. EnableWindow( GetDlgItem( hwnd , nId[ idx ] ) , FALSE );
  730. }
  731. ErrorMessage1( hwnd , dwStatus );
  732. return FALSE;
  733. }
  734. //
  735. // First thing is to set the default values for all the controls
  736. //
  737. HWND hCombo[ 3 ] =
  738. {
  739. GetDlgItem( hwnd , IDC_COMBO_CONNECT ),
  740. GetDlgItem( hwnd , IDC_COMBO_DISCON ),
  741. GetDlgItem( hwnd , IDC_COMBO_IDLE )
  742. };
  743. for( int idx = 0; rgdwTime[ idx ] != ( DWORD)-1; ++idx )
  744. {
  745. if( rgdwTime[ idx ] == 0 )
  746. {
  747. LoadString( _Module.GetResourceInstance( ) , IDS_NOTIMEOUT , tchBuffer , sizeof( tchBuffer ) / sizeof( TCHAR ) );
  748. }
  749. else
  750. {
  751. ConvertToDuration( rgdwTime[ idx ] , tchBuffer );
  752. }
  753. for( int inner = 0 ; inner < 3 ; ++inner )
  754. {
  755. SendMessage( hCombo[ inner ] , CB_ADDSTRING , 0 , ( LPARAM )&tchBuffer[0] );
  756. SendMessage( hCombo[ inner ] , CB_SETITEMDATA , idx , rgdwTime[ idx ] );
  757. }
  758. }
  759. ULONG ulTime;
  760. if( uc.MaxConnectionTime > 0 )
  761. {
  762. ulTime = uc.MaxConnectionTime / kMilliMinute;
  763. // hCombo[ 0 ] == IDC_COMBO_CONNECT
  764. InsertSortedAndSetCurSel( hCombo[ 0 ] , ulTime );
  765. }
  766. else
  767. {
  768. SendMessage( hCombo[ 0 ] , CB_SETCURSEL , 0 , 0 );
  769. }
  770. //
  771. // Set the current or default disconnection timeout
  772. //
  773. if( uc.MaxDisconnectionTime > 0 )
  774. {
  775. ulTime = uc.MaxDisconnectionTime / kMilliMinute;
  776. // hCombo[ 1 ] == IDC_COMBO_DISCON
  777. InsertSortedAndSetCurSel( hCombo[ 1 ] , ulTime );
  778. }
  779. else
  780. {
  781. SendMessage( hCombo[ 1] , CB_SETCURSEL , 0 , 0 );
  782. }
  783. //
  784. // Set the current or default idle timeout
  785. //
  786. if( uc.MaxIdleTime > 0 )
  787. {
  788. ulTime = uc.MaxIdleTime / kMilliMinute;
  789. // hCombo[ 2 ] == IDC_COMBO_IDLE
  790. InsertSortedAndSetCurSel( hCombo[ 2 ] , ulTime );
  791. }
  792. else
  793. {
  794. SendMessage( hCombo[ 2 ] , CB_SETCURSEL , 0 , 0 );
  795. }
  796. //
  797. // Set remaining controls to current settings
  798. //
  799. if( uc.fResetBroken )
  800. {
  801. SendMessage( GetDlgItem( hwnd , IDC_RADIO_RESET ) , BM_CLICK , 0 , 0 );
  802. m_wAction = IDC_RADIO_RESET;
  803. }
  804. else
  805. {
  806. SendMessage( GetDlgItem( hwnd , IDC_RADIO_DISCON ) , BM_CLICK , 0 , 0 );
  807. m_wAction = IDC_RADIO_DISCON;
  808. }
  809. if( uc.fReconnectSame )
  810. {
  811. SendMessage( GetDlgItem( hwnd , IDC_RADIO_PREVCLIENT ) , BM_CLICK , 0 ,0 );
  812. m_wCon = IDC_RADIO_PREVCLIENT;
  813. }
  814. else
  815. {
  816. SendMessage( GetDlgItem( hwnd , IDC_RADIO_ANYCLIENT ) , BM_CLICK , 0 , 0 );
  817. m_wCon = IDC_RADIO_ANYCLIENT;
  818. }
  819. LoadAbbreviates( );
  820. m_bPersisted = TRUE;
  821. return CDialogBase::OnInitDialog( hwnd , wp , lp );
  822. }
  823. //-------------------------------------------------------------------------------
  824. // TimeOutDlg Dialog Page
  825. // -- static methods lacks this ptr
  826. //-------------------------------------------------------------------------------
  827. INT_PTR CALLBACK CTimeOutDlg::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  828. {
  829. CTimeOutDlg *pDlg;
  830. if( msg == WM_INITDIALOG )
  831. {
  832. CTimeOutDlg *pDlg = ( CTimeOutDlg * )( ( PROPSHEETPAGE *)lp )->lParam ;
  833. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  834. if( !IsBadReadPtr( pDlg , sizeof( CTimeOutDlg ) ) )
  835. {
  836. pDlg->OnInitDialog( hwnd , wp , lp );
  837. }
  838. return 0;
  839. }
  840. else
  841. {
  842. pDlg = ( CTimeOutDlg * )GetWindowLongPtr( hwnd , DWLP_USER );
  843. if( IsBadReadPtr( pDlg , sizeof( CTimeOutDlg ) ) )
  844. {
  845. return FALSE;
  846. }
  847. }
  848. switch( msg )
  849. {
  850. case WM_NCDESTROY:
  851. pDlg->OnDestroy( );
  852. break;
  853. case WM_COMMAND:
  854. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  855. break;
  856. case WM_NOTIFY:
  857. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  858. case WM_HELP:
  859. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  860. break;
  861. case WM_RBUTTONUP:
  862. {
  863. POINT pt;
  864. pt.x = LOWORD( lp );
  865. pt.y = HIWORD( lp );
  866. HWND hChild = ChildWindowFromPoint( hwnd , pt );
  867. ClientToScreen( hwnd , &pt );
  868. pDlg->OnContextMenu( hChild , pt );
  869. }
  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. }
  879. return 0;
  880. }
  881. BOOL CTimeOutDlg::OnDestroy( )
  882. {
  883. xxxUnLoadAbbreviate( &m_tokday[0] );
  884. xxxUnLoadAbbreviate( &m_tokhour[0] );
  885. xxxUnLoadAbbreviate( &m_tokmin[0] );
  886. return CDialogBase::OnDestroy( );
  887. }
  888. //-------------------------------------------------------------------------------
  889. // GetPropertySheetPage - each dialog object should be responsible for its own data
  890. //-------------------------------------------------------------------------------
  891. BOOL CTimeOutDlg::GetPropertySheetPage( PROPSHEETPAGE &psp)
  892. {
  893. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  894. psp.dwSize = sizeof( PROPSHEETPAGE );
  895. psp.dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
  896. psp.hInstance = _Module.GetModuleInstance( );
  897. psp.pszTemplate = MAKEINTRESOURCE( IDD_PAGE_TIMEOUTS );
  898. psp.lParam = (LPARAM)this;
  899. psp.pfnCallback = CDialogBase::PageCallback;
  900. psp.pfnDlgProc = CTimeOutDlg::DlgProc;
  901. return TRUE;
  902. }
  903. //-------------------------------------------------------------------------------
  904. // OnCommand
  905. //-------------------------------------------------------------------------------
  906. void CTimeOutDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtl )
  907. {
  908. switch( wNotifyCode )
  909. {
  910. case CBN_EDITCHANGE:
  911. OnCBEditChange( hwndCtl );
  912. m_bPersisted = FALSE;
  913. break;
  914. case CBN_SELCHANGE:
  915. if( SendMessage( hwndCtl , CB_GETDROPPEDSTATE , 0 ,0 ) == TRUE )
  916. {
  917. return;
  918. }
  919. OnCBNSELCHANGE( hwndCtl ); // FALLTHROUGH
  920. // m_bPersisted = FALSE;
  921. break;
  922. case BN_CLICKED:
  923. if( wID == IDC_RADIO_DISCON || wID == IDC_RADIO_RESET )
  924. {
  925. if( m_wAction != wID )
  926. {
  927. m_wAction = wID;
  928. m_bPersisted = FALSE;
  929. }
  930. }
  931. else if( wID == IDC_RADIO_PREVCLIENT || wID == IDC_RADIO_ANYCLIENT )
  932. {
  933. if( m_wCon != wID )
  934. {
  935. m_wCon = wID;
  936. m_bPersisted = FALSE;
  937. }
  938. }
  939. break;
  940. //case CBN_DROPDOWN: // FALLTHROUGH
  941. case CBN_KILLFOCUS:
  942. ODS( L"CBN_KILLFOCUS\n");
  943. if( !OnCBDropDown( hwndCtl ) )
  944. {
  945. return;
  946. }
  947. m_bPersisted = FALSE;
  948. break;
  949. case ALN_APPLY:
  950. //This is being removed for consinstency with the rest of MMC dialogs, even though it would
  951. //make more sense to the user for Cancel to be disabled after applying the changes, since
  952. //cancellation is not a real option at that point.
  953. //SendMessage( GetParent( hwndCtl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  954. return;
  955. }
  956. if( !m_bPersisted )
  957. {
  958. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  959. }
  960. }
  961. //-------------------------------------------------------------------------------
  962. // Update the entry if it has been modified by user
  963. //-------------------------------------------------------------------------------
  964. BOOL CTimeOutDlg::OnCBDropDown( HWND hCombo )
  965. {
  966. TCHAR tchBuffer[ 80 ];
  967. ULONG ulTime = 0;
  968. int i = GetCBXSTATEindex( hCombo );
  969. if( i < 0 )
  970. {
  971. return FALSE;
  972. }
  973. if( m_cbxst[ i ].bEdit )
  974. {
  975. GetWindowText( hCombo , tchBuffer , sizeof( tchBuffer ) / sizeof( TCHAR ) );
  976. if( ParseDurationEntry( tchBuffer , &ulTime ) == E_SUCCESS )
  977. {
  978. InsertSortedAndSetCurSel( hCombo , ulTime );
  979. }
  980. }
  981. return m_cbxst[ i ].bEdit;
  982. }
  983. //-------------------------------------------------------------------------------
  984. // Use this flag to distinguish between hand entry or listbox selection
  985. // setting it to true implies that the use has edit the cbx via typing
  986. //-------------------------------------------------------------------------------
  987. void CTimeOutDlg::OnCBEditChange( HWND hCombo )
  988. {
  989. int i = GetCBXSTATEindex( hCombo );
  990. if( i > -1 )
  991. {
  992. m_cbxst[ i ].bEdit = TRUE;
  993. }
  994. }
  995. //-------------------------------------------------------------------------------
  996. // Determine if user wants to enter a custom time
  997. //-------------------------------------------------------------------------------
  998. void CTimeOutDlg::OnCBNSELCHANGE( HWND hwnd )
  999. {
  1000. if( SaveChangedSelection( hwnd ) )
  1001. {
  1002. m_bPersisted = FALSE;
  1003. }
  1004. }
  1005. //-------------------------------------------------------------------------------
  1006. // Saves selected item.
  1007. //-------------------------------------------------------------------------------
  1008. BOOL CTimeOutDlg::SaveChangedSelection( HWND hCombo )
  1009. {
  1010. LRESULT idx = SendMessage( hCombo , CB_GETCURSEL , 0 , 0 );
  1011. int i = GetCBXSTATEindex( hCombo );
  1012. if( i > -1 )
  1013. {
  1014. if( idx != ( LRESULT )m_cbxst[ i ].icbxSel )
  1015. {
  1016. m_cbxst[ i ].icbxSel = (int)idx;
  1017. m_cbxst[ i ].bEdit = FALSE;
  1018. return TRUE;
  1019. }
  1020. }
  1021. return FALSE;
  1022. }
  1023. //-------------------------------------------------------------------------------
  1024. // Restore previous setting
  1025. //-------------------------------------------------------------------------------
  1026. BOOL CTimeOutDlg::RestorePreviousValue( HWND hwnd )
  1027. {
  1028. int iSel;
  1029. if( ( iSel = GetCBXSTATEindex( hwnd ) ) > -1 )
  1030. {
  1031. SendMessage( hwnd , CB_SETCURSEL , m_cbxst[ iSel ].icbxSel , 0 );
  1032. return TRUE;
  1033. }
  1034. return FALSE;
  1035. }
  1036. //-------------------------------------------------------------------------------
  1037. // returns the indx in m_cbxst of which hcombo is assoc. with
  1038. //-------------------------------------------------------------------------------
  1039. int CTimeOutDlg::GetCBXSTATEindex( HWND hCombo )
  1040. {
  1041. int idx = -1;
  1042. switch( GetDlgCtrlID( hCombo ) )
  1043. {
  1044. case IDC_COMBO_CONNECT:
  1045. idx = 0;
  1046. break;
  1047. case IDC_COMBO_DISCON:
  1048. idx = 1;
  1049. break;
  1050. case IDC_COMBO_IDLE:
  1051. idx = 2;
  1052. break;
  1053. }
  1054. return idx;
  1055. }
  1056. //-------------------------------------------------------------------------------
  1057. // ConvertToMinutes -- helper for CTimeOutDlg::OnNotify
  1058. //-------------------------------------------------------------------------------
  1059. BOOL CTimeOutDlg::ConvertToMinutes( HWND hwndCtl , PULONG pulMinutes )
  1060. {
  1061. TCHAR tchBuffer[ 80 ];
  1062. TCHAR tchErrTitle[ 80 ];
  1063. TCHAR tchErrMsg[ 256 ];
  1064. TCHAR tchErrItem[ 80 ];
  1065. TCHAR tchErrTot[ 336 ];
  1066. int nComboResID[] = { IDS_COMBO_CONNECTION , IDS_COMBO_DISCONNECTION , IDS_COMBO_IDLECONNECTION };
  1067. int idx = GetCBXSTATEindex( hwndCtl );
  1068. if( idx < 0 )
  1069. {
  1070. return FALSE;
  1071. }
  1072. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , sizeof( tchErrTitle ) / sizeof( TCHAR ) );
  1073. if( m_cbxst[ idx ].bEdit )
  1074. {
  1075. ODS( TEXT( "Manual Entry parsing\n") );
  1076. if( GetWindowText( hwndCtl , tchBuffer , sizeof( tchBuffer ) / sizeof( TCHAR ) ) < 1 )
  1077. {
  1078. *pulMinutes = 0;
  1079. return TRUE;
  1080. }
  1081. LRESULT lr = ParseDurationEntry( tchBuffer , pulMinutes );
  1082. if( lr != E_SUCCESS )
  1083. {
  1084. LoadString( _Module.GetResourceInstance( ) , nComboResID[ idx ] , tchErrItem , sizeof( tchErrItem ) / sizeof( TCHAR ) );
  1085. if( lr == E_PARSE_VALUEOVERFLOW )
  1086. {
  1087. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TOOMANYDIGITS , tchErrMsg , sizeof( tchErrMsg ) / sizeof( TCHAR ) );
  1088. wsprintf( tchErrTot , tchErrMsg , tchErrItem );
  1089. MessageBox( hwndCtl , tchErrTot , tchErrTitle , MB_OK | MB_ICONERROR );
  1090. SetFocus( hwndCtl );
  1091. }
  1092. else if( lr == E_PARSE_MISSING_DIGITS || lr == E_PARSE_INVALID )
  1093. {
  1094. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_PARSEINVALID , tchErrMsg , sizeof( tchErrMsg ) / sizeof( TCHAR ) );
  1095. wsprintf( tchErrTot , tchErrMsg , tchErrItem );
  1096. MessageBox( hwndCtl , tchErrTot , tchErrTitle , MB_OK | MB_ICONERROR );
  1097. SetFocus( hwndCtl );
  1098. }
  1099. return FALSE;
  1100. }
  1101. }
  1102. else
  1103. {
  1104. ODS( L"Getting current selection\n" );
  1105. LONG_PTR iCurSel = SendMessage( hwndCtl , CB_GETCURSEL , 0 , 0 );
  1106. LONG_PTR lData;
  1107. // See if user wants "No Timeout"
  1108. if( iCurSel == 0 )
  1109. {
  1110. *pulMinutes = 0;
  1111. return TRUE;
  1112. }
  1113. if( ( lData = SendMessage( hwndCtl , CB_GETITEMDATA , iCurSel , 0 ) ) == CB_ERR )
  1114. {
  1115. *pulMinutes = 0;
  1116. } else {
  1117. *pulMinutes = (ULONG)lData;
  1118. }
  1119. }
  1120. if( *pulMinutes > kMaxTimeoutMinute )
  1121. {
  1122. LoadString( _Module.GetResourceInstance( ) , nComboResID[ idx ] , tchErrItem , sizeof( tchErrItem ) / sizeof( TCHAR ) );
  1123. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_MAXVALEXCEEDED , tchErrMsg , sizeof( tchErrMsg ) / sizeof( TCHAR ) );
  1124. wsprintf( tchErrTot , tchErrMsg , tchErrItem );
  1125. MessageBox( hwndCtl , tchErrTot , tchErrTitle , MB_OK | MB_ICONERROR );
  1126. SetFocus( hwndCtl );
  1127. return FALSE;
  1128. }
  1129. *pulMinutes *= kMilliMinute;
  1130. return TRUE;
  1131. }
  1132. //-------------------------------------------------------------------------------
  1133. // PersistSettings
  1134. //-------------------------------------------------------------------------------
  1135. BOOL CTimeOutDlg::PersistSettings( HWND hDlg )
  1136. {
  1137. DWORD dwStatus;
  1138. if( IsBadReadPtr( m_pUSht , sizeof( CTSUserSheet ) ) )
  1139. {
  1140. return FALSE;
  1141. }
  1142. USERCONFIG uc;
  1143. uc = m_pUSht->GetCurrentUserConfig( &dwStatus );
  1144. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_CONNECT ) , &uc.MaxConnectionTime ) )
  1145. {
  1146. return FALSE;
  1147. }
  1148. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_DISCON ) , &uc.MaxDisconnectionTime ) )
  1149. {
  1150. return FALSE;
  1151. }
  1152. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_IDLE ) , &uc.MaxIdleTime ) )
  1153. {
  1154. return FALSE;
  1155. }
  1156. uc.fResetBroken = SendMessage( GetDlgItem( hDlg , IDC_RADIO_RESET ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  1157. uc.fReconnectSame = SendMessage( GetDlgItem( hDlg , IDC_RADIO_PREVCLIENT ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  1158. if( !m_pUSht->SetUserConfig( uc , &dwStatus ) )
  1159. {
  1160. ErrorMessage2( hDlg , dwStatus );
  1161. return TRUE;
  1162. }
  1163. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  1164. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  1165. return TRUE;
  1166. }
  1167. //-------------------------------------------------------------------------------
  1168. // Making sure the user has entered valid info
  1169. //-------------------------------------------------------------------------------
  1170. BOOL CTimeOutDlg::IsValidSettings( HWND hDlg )
  1171. {
  1172. DWORD dwDummy;
  1173. if( IsBadReadPtr( m_pUSht , sizeof( CTSUserSheet ) ) )
  1174. {
  1175. return FALSE;
  1176. }
  1177. USERCONFIG uc;
  1178. uc = m_pUSht->GetCurrentUserConfig( &dwDummy );
  1179. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_CONNECT ) , &uc.MaxConnectionTime ) )
  1180. {
  1181. return FALSE;
  1182. }
  1183. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_DISCON ) , &uc.MaxDisconnectionTime ) )
  1184. {
  1185. return FALSE;
  1186. }
  1187. if( !ConvertToMinutes( GetDlgItem( hDlg , IDC_COMBO_IDLE ) , &uc.MaxIdleTime ) )
  1188. {
  1189. return FALSE;
  1190. }
  1191. return TRUE;
  1192. }
  1193. #if 0
  1194. //-------------------------------------------------------------------------------
  1195. // Lets cut to the chase and find out if this is even worth parsing
  1196. //-------------------------------------------------------------------------------
  1197. BOOL CTimeOutDlg::DoesContainDigits( LPTSTR pszString )
  1198. {
  1199. while( *pszString )
  1200. {
  1201. if( iswdigit( *pszString ) )
  1202. {
  1203. return TRUE;
  1204. }
  1205. pszString++;
  1206. }
  1207. return FALSE;
  1208. }
  1209. //-------------------------------------------------------------------------------
  1210. LRESULT CTimeOutDlg::ParseDurationEntry( LPTSTR pszTime , PULONG pTime )
  1211. {
  1212. TCHAR tchNoTimeout[ 80 ];
  1213. LPTSTR pszTemp = pszTime;
  1214. UINT uDec = 0;
  1215. float fFrac = 0.0f;
  1216. float fT;
  1217. UINT uPos = 1;
  1218. LoadString( _Module.GetResourceInstance( ) , IDS_NOTIMEOUT , tchNoTimeout , sizeof( tchNoTimeout ) / sizeof( TCHAR ) );
  1219. if( lstrcmpi( pszTime , tchNoTimeout ) == 0 )
  1220. {
  1221. *pTime = 0;
  1222. return E_SUCCESS;
  1223. }
  1224. if( !DoesContainDigits( pszTime ) )
  1225. {
  1226. return E_PARSE_MISSING_DIGITS;
  1227. }
  1228. while( *pszTemp )
  1229. {
  1230. if( !iswdigit( *pszTemp ) )
  1231. {
  1232. break;
  1233. }
  1234. // check for overflow
  1235. if( uDec >= 1000000000 )
  1236. {
  1237. return E_PARSE_VALUEOVERFLOW ;
  1238. }
  1239. uDec *= 10;
  1240. uDec += ( *pszTemp - '0' );
  1241. pszTemp++;
  1242. }
  1243. TCHAR tchSDecimal[ 5 ];
  1244. GetLocaleInfo( LOCALE_USER_DEFAULT , LOCALE_SDECIMAL , tchSDecimal , sizeof( tchSDecimal ) / sizeof( TCHAR ) );
  1245. if( *pszTemp == *tchSDecimal )
  1246. {
  1247. pszTemp++;
  1248. while( *pszTemp )
  1249. {
  1250. if( !iswdigit( *pszTemp ) )
  1251. {
  1252. break;
  1253. }
  1254. // check for overflow
  1255. if( uDec >= 1000000000 )
  1256. {
  1257. return E_PARSE_VALUEOVERFLOW;
  1258. }
  1259. uPos *= 10;
  1260. fFrac += ( ( float )( *pszTemp - '0' ) ) / ( float )uPos; //+ 0.05f;
  1261. pszTemp++;
  1262. }
  1263. }
  1264. // remove white space
  1265. while( *pszTemp == L' ' )
  1266. {
  1267. pszTemp++;
  1268. }
  1269. if( *pszTemp != NULL )
  1270. {
  1271. if( IsToken( pszTemp , TOKEN_DAY ) )
  1272. {
  1273. *pTime = uDec * 24 * 60;
  1274. fT = ( fFrac * 1440.0f + 0.5f );
  1275. *pTime += ( ULONG )fT;
  1276. return E_SUCCESS;
  1277. }
  1278. else if( IsToken( pszTemp , TOKEN_HOUR ) )
  1279. {
  1280. *pTime = uDec * 60;
  1281. fT = ( fFrac * 60.0f + 0.5f );
  1282. *pTime += ( ULONG )fT;
  1283. return E_SUCCESS;
  1284. }
  1285. else if( IsToken( pszTemp , TOKEN_MINUTE ) )
  1286. {
  1287. // minutes are rounded up in the 1/10 place
  1288. fT = fFrac + 0.5f;
  1289. *pTime = uDec;
  1290. *pTime += ( ULONG )( fT );
  1291. return E_SUCCESS;
  1292. }
  1293. }
  1294. if( *pszTemp == NULL )
  1295. {
  1296. // if no text is defined considered the entry in hours
  1297. *pTime = uDec * 60;
  1298. fT = ( fFrac * 60.0f + 0.5f );
  1299. *pTime += ( ULONG )fT ;
  1300. return E_SUCCESS;
  1301. }
  1302. return E_PARSE_INVALID;
  1303. }
  1304. #endif
  1305. //-------------------------------------------------------------------------------
  1306. // Adds strings to table from resource
  1307. //-------------------------------------------------------------------------------
  1308. BOOL CTimeOutDlg::LoadAbbreviates( )
  1309. {
  1310. xxxLoadAbbreviate( &m_tokday[0] );
  1311. xxxLoadAbbreviate( &m_tokhour[0] );
  1312. xxxLoadAbbreviate( &m_tokmin[0] );
  1313. return TRUE;
  1314. }
  1315. //-------------------------------------------------------------------------------
  1316. // Take cares some repetitive work for us
  1317. //-------------------------------------------------------------------------------
  1318. BOOL CTimeOutDlg::xxxLoadAbbreviate( PTOKTABLE ptoktbl )
  1319. {
  1320. int idx;
  1321. int nSize;
  1322. TCHAR tchbuffer[ 80 ];
  1323. if( ptoktbl == NULL )
  1324. {
  1325. return FALSE;
  1326. }
  1327. for( idx = 0; ptoktbl[ idx ].dwresourceid != ( DWORD )-1 ; ++idx )
  1328. {
  1329. nSize = LoadString( _Module.GetResourceInstance( ) , ptoktbl[ idx ].dwresourceid , tchbuffer , sizeof( tchbuffer ) / sizeof( TCHAR ) );
  1330. if( nSize > 0 )
  1331. {
  1332. ptoktbl[ idx ].pszAbbrv = ( TCHAR *)new TCHAR[ nSize + 1 ];
  1333. if( ptoktbl[ idx ].pszAbbrv != NULL )
  1334. {
  1335. lstrcpy( ptoktbl[ idx ].pszAbbrv , tchbuffer );
  1336. }
  1337. }
  1338. }
  1339. return TRUE;
  1340. }
  1341. //-------------------------------------------------------------------------------
  1342. // Frees up allocated resources
  1343. //-------------------------------------------------------------------------------
  1344. BOOL CTimeOutDlg::xxxUnLoadAbbreviate( PTOKTABLE ptoktbl )
  1345. {
  1346. if( ptoktbl == NULL )
  1347. {
  1348. return FALSE;
  1349. }
  1350. for( int idx = 0; ptoktbl[ idx ].dwresourceid != ( DWORD )-1 ; ++idx )
  1351. {
  1352. if( ptoktbl[ idx ].pszAbbrv != NULL )
  1353. {
  1354. delete[] ptoktbl[ idx ].pszAbbrv;
  1355. }
  1356. }
  1357. return TRUE;
  1358. }
  1359. //-------------------------------------------------------------------------------
  1360. // tear-off token tables
  1361. //-------------------------------------------------------------------------------
  1362. BOOL CTimeOutDlg::IsToken( LPTSTR pszString , TOKEN tok )
  1363. {
  1364. TOKTABLE *ptoktable;
  1365. if( tok == TOKEN_DAY )
  1366. {
  1367. ptoktable = &m_tokday[0];
  1368. }
  1369. else if( tok == TOKEN_HOUR )
  1370. {
  1371. ptoktable = &m_tokhour[0];
  1372. }
  1373. else if( tok == TOKEN_MINUTE )
  1374. {
  1375. ptoktable = &m_tokmin[0];
  1376. }
  1377. else
  1378. {
  1379. return FALSE;
  1380. }
  1381. for( int idx = 0 ; ptoktable[ idx ].dwresourceid != -1 ; ++idx )
  1382. {
  1383. if( lstrcmpi( pszString , ptoktable[ idx ].pszAbbrv ) == 0 )
  1384. {
  1385. return TRUE;
  1386. }
  1387. }
  1388. return FALSE;
  1389. }
  1390. #if 0
  1391. //-------------------------------------------------------------------------------
  1392. // Converts the number minutes into a formated string
  1393. //-------------------------------------------------------------------------------
  1394. BOOL CTimeOutDlg::ConvertToDuration( ULONG ulTime , LPTSTR pszDuration )
  1395. {
  1396. INT_PTR dw[3];
  1397. TCHAR tchTimeUnit[ 40 ];
  1398. TCHAR tchTimeFormat[ 40 ];
  1399. TCHAR tchOutput[ 80 ];
  1400. ASSERT_( ulTime != 0 );
  1401. int iHour= ( int ) ( ( float )ulTime / 60.0f );
  1402. int iDays = iHour / 24;
  1403. dw[ 2 ] = ( INT_PTR )&tchTimeUnit[ 0 ];
  1404. LoadString( _Module.GetResourceInstance( ) , IDS_DIGIT_DOT_DIGIT_TU , tchTimeFormat , sizeof( tchTimeFormat ) / sizeof( TCHAR ) );
  1405. if( iDays != 0 )
  1406. {
  1407. int iRemainingHours = iHour % 24;
  1408. float fx = ( float )iRemainingHours / 24.0f + 0.05f;
  1409. int iRemainingMinutes = ulTime % 60;
  1410. float mfx = ( float )iRemainingMinutes / 60.0f + 0.05f;
  1411. //if( ( iRemainingHours != 0 || iRemainingMinutes != 0 ) && iDays < 2 )
  1412. if( mfx > 0.05f || ( fx > 0.05f && fx < 0.10f && iDays < 2 ) )//
  1413. {
  1414. iRemainingMinutes = ( int ) ( mfx * 10 );
  1415. dw[ 0 ] = iHour;
  1416. dw[ 1 ] = iRemainingMinutes;
  1417. iDays = 0;
  1418. LoadString( _Module.GetResourceInstance( ) , IDS_HOURS , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1419. }
  1420. else
  1421. {
  1422. iRemainingHours = ( int )( fx * 10 );
  1423. LoadString( _Module.GetResourceInstance( ) , IDS_DAYS , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1424. dw[ 0 ] = iDays;
  1425. dw[ 1 ] = iRemainingHours;
  1426. }
  1427. if( dw[ 1 ] == 0 )
  1428. {
  1429. // formatted string requires two arguments
  1430. dw[ 1 ] = ( INT_PTR )&tchTimeUnit[ 0 ];
  1431. LoadString( _Module.GetResourceInstance( ) , IDS_DIGIT_TU , tchTimeFormat , sizeof( tchTimeFormat ) / sizeof( TCHAR ) );
  1432. if( iDays == 1 )
  1433. {
  1434. LoadString( _Module.GetResourceInstance( ) , IDS_DAY , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1435. }
  1436. }
  1437. }
  1438. else if( iHour != 0 )
  1439. {
  1440. int iRemainingMinutes = ulTime % 60;
  1441. float fx = ( float )iRemainingMinutes / 60.0f ;//+ 0.05f;
  1442. if( fx > 0.0f && fx < 0.10f && iHour < 2 )//
  1443. {
  1444. LoadString( _Module.GetResourceInstance( ) , IDS_MINUTES , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1445. LoadString( _Module.GetResourceInstance( ) , IDS_DIGIT_TU , tchTimeFormat , sizeof( tchTimeFormat ) / sizeof( TCHAR ) );
  1446. dw[ 0 ] = ulTime ;
  1447. dw[ 1 ] = ( INT_PTR )&tchTimeUnit[ 0 ];
  1448. if( ulTime > 1 )
  1449. {
  1450. LoadString( _Module.GetResourceInstance( ) , IDS_MINUTES , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1451. }
  1452. else
  1453. {
  1454. LoadString( _Module.GetResourceInstance( ) , IDS_MINUTE , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1455. }
  1456. }//
  1457. else
  1458. {
  1459. fx += 0.05f;
  1460. iRemainingMinutes = ( int ) ( fx * 10 );
  1461. dw[ 0 ] = iHour;
  1462. dw[ 1 ] = iRemainingMinutes;
  1463. LoadString( _Module.GetResourceInstance( ) , IDS_HOURS , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1464. if( iRemainingMinutes == 0 )
  1465. {
  1466. dw[ 1 ] = ( INT_PTR )&tchTimeUnit[ 0 ];
  1467. LoadString( _Module.GetResourceInstance( ) , IDS_DIGIT_TU , tchTimeFormat , sizeof( tchTimeFormat ) / sizeof( TCHAR ) );
  1468. if( iHour == 1 )
  1469. {
  1470. LoadString( _Module.GetResourceInstance( ) , IDS_HOUR , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1471. }
  1472. }
  1473. }
  1474. }
  1475. else
  1476. {
  1477. LoadString( _Module.GetResourceInstance( ) , IDS_MINUTES , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1478. LoadString( _Module.GetResourceInstance( ) , IDS_DIGIT_TU , tchTimeFormat , sizeof( tchTimeFormat ) / sizeof( TCHAR ) );
  1479. dw[ 0 ] = ulTime ;
  1480. dw[ 1 ] = ( INT_PTR )&tchTimeUnit[ 0 ];
  1481. if( ulTime > 1 )
  1482. {
  1483. LoadString( _Module.GetResourceInstance( ) , IDS_MINUTES , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1484. }
  1485. else
  1486. {
  1487. LoadString( _Module.GetResourceInstance( ) , IDS_MINUTE , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  1488. }
  1489. }
  1490. FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, tchTimeFormat , 0 , 0 , tchOutput , sizeof( tchOutput )/sizeof( TCHAR ) , ( va_list * )&dw );
  1491. lstrcpy( pszDuration , tchOutput );
  1492. return TRUE;
  1493. }
  1494. #endif
  1495. //-------------------------------------------------------------------------------
  1496. // Place entry in listbox and set as current selection
  1497. //-------------------------------------------------------------------------------
  1498. BOOL CTimeOutDlg::InsertSortedAndSetCurSel( HWND hCombo , DWORD dwMinutes )
  1499. {
  1500. ASSERT_( dwMinutes != ( DWORD )-1 );
  1501. TCHAR tchBuffer[ 80 ];
  1502. LRESULT iCount = SendMessage( hCombo , CB_GETCOUNT , 0 , 0 );
  1503. for( INT_PTR idx = 0 ; idx < iCount ; ++idx )
  1504. {
  1505. // Don't insert an item that's already in the list
  1506. if( dwMinutes == ( DWORD )SendMessage( hCombo , CB_GETITEMDATA , idx , 0 ) )
  1507. {
  1508. SendMessage( hCombo , CB_SETCURSEL , idx , 0 ) ;
  1509. SaveChangedSelection( hCombo );
  1510. return TRUE;
  1511. }
  1512. if( dwMinutes < ( DWORD )SendMessage( hCombo , CB_GETITEMDATA , idx , 0 ) )
  1513. {
  1514. break;
  1515. }
  1516. }
  1517. // hey if the value has exceeded the max timeout don't bother entering it in our list
  1518. if( dwMinutes > kMaxTimeoutMinute )
  1519. {
  1520. return FALSE;
  1521. }
  1522. if( ConvertToDuration ( dwMinutes , tchBuffer ) )
  1523. {
  1524. idx = SendMessage( hCombo , CB_INSERTSTRING , idx , ( LPARAM )&tchBuffer[ 0 ] );
  1525. if( idx != CB_ERR )
  1526. {
  1527. SendMessage( hCombo , CB_SETITEMDATA , idx , dwMinutes );
  1528. }
  1529. SendMessage( hCombo , CB_SETCURSEL , idx , 0 ) ;
  1530. }
  1531. // must call this here because CB_SETCURSEL does not send CBN_SELCHANGE
  1532. SaveChangedSelection( hCombo );
  1533. return TRUE;
  1534. }
  1535. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  1536. //-------------------------------------------------------------------------------
  1537. // CShadowDlg::ctor
  1538. //-------------------------------------------------------------------------------
  1539. CShadowDlg::CShadowDlg( CTSUserSheet *pUSht )
  1540. {
  1541. m_pUSht = pUSht;
  1542. m_wOldRad = ( WORD )-1;
  1543. }
  1544. //-------------------------------------------------------------------------------
  1545. // CShadowDlg Dialog Page
  1546. // -- static methods lacks this ptr
  1547. //-------------------------------------------------------------------------------
  1548. INT_PTR CALLBACK CShadowDlg::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  1549. {
  1550. CShadowDlg *pDlg;
  1551. if( msg == WM_INITDIALOG )
  1552. {
  1553. CShadowDlg *pDlg = ( CShadowDlg * )( ( PROPSHEETPAGE *)lp )->lParam ;
  1554. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  1555. if( !IsBadReadPtr( pDlg , sizeof( CShadowDlg ) ) )
  1556. {
  1557. pDlg->OnInitDialog( hwnd , wp , lp );
  1558. }
  1559. return 0;
  1560. }
  1561. else
  1562. {
  1563. pDlg = ( CShadowDlg * )GetWindowLongPtr( hwnd , DWLP_USER );
  1564. if( IsBadReadPtr( pDlg , sizeof( CShadowDlg ) ) )
  1565. {
  1566. return FALSE;
  1567. }
  1568. }
  1569. switch( msg )
  1570. {
  1571. case WM_NCDESTROY:
  1572. pDlg->OnDestroy( );
  1573. break;
  1574. case WM_COMMAND:
  1575. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  1576. break;
  1577. case WM_NOTIFY:
  1578. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  1579. case WM_HELP:
  1580. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  1581. break;
  1582. case WM_RBUTTONUP:
  1583. {
  1584. POINT pt;
  1585. pt.x = LOWORD( lp );
  1586. pt.y = HIWORD( lp );
  1587. HWND hChild = ChildWindowFromPoint( hwnd , pt );
  1588. ClientToScreen( hwnd , &pt );
  1589. pDlg->OnContextMenu( hChild , pt );
  1590. }
  1591. break;
  1592. case WM_CONTEXTMENU:
  1593. {
  1594. POINT pt;
  1595. pt.x = LOWORD( lp );
  1596. pt.y = HIWORD( lp );
  1597. pDlg->OnContextMenu( ( HWND )wp , pt );
  1598. }
  1599. }
  1600. return 0;
  1601. }
  1602. //-------------------------------------------------------------------------------
  1603. // InitDialog for CShadowDlg
  1604. //-------------------------------------------------------------------------------
  1605. BOOL CShadowDlg::OnInitDialog( HWND hwnd , WPARAM wp , LPARAM lp )
  1606. {
  1607. DWORD dwStatus;
  1608. if( IsBadReadPtr( m_pUSht ,sizeof( CTSUserSheet ) ) )
  1609. {
  1610. return FALSE;
  1611. }
  1612. USERCONFIG uc;
  1613. uc = m_pUSht->GetCurrentUserConfig( &dwStatus );
  1614. // No userconfig loaded most likey access denied donot allow users to modify anything
  1615. if( dwStatus != ERROR_FILE_NOT_FOUND && dwStatus != ERROR_SUCCESS )
  1616. {
  1617. INT nId[ ] = {
  1618. IDC_CHECK_SHADOW,
  1619. IDC_RADIO_WATCH,
  1620. IDC_RADIO_CONTROL,
  1621. IDC_CHECK_NOTIFY,
  1622. -1
  1623. };
  1624. for( int idx = 0; nId[ idx ] != -1 ; ++idx )
  1625. {
  1626. EnableWindow( GetDlgItem( hwnd , nId[ idx ] ) , FALSE );
  1627. }
  1628. ErrorMessage1( hwnd , dwStatus );
  1629. return FALSE;
  1630. }
  1631. if( uc.Shadow == Shadow_Disable )
  1632. {
  1633. SendMessage( GetDlgItem( hwnd , IDC_CHECK_SHADOW ) , BM_SETCHECK , ( WPARAM )FALSE , 0 );
  1634. EnableWindow( GetDlgItem( hwnd , IDC_RADIO_WATCH ) , FALSE );
  1635. EnableWindow( GetDlgItem( hwnd , IDC_RADIO_CONTROL ) , FALSE );
  1636. EnableWindow( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , FALSE );
  1637. EnableWindow( GetDlgItem( hwnd , IDC_STATIC_LEVELOFCTRL ) , FALSE );
  1638. }
  1639. else
  1640. {
  1641. //
  1642. // Controls are initially enabled, set current status
  1643. //
  1644. SendMessage( GetDlgItem( hwnd , IDC_CHECK_SHADOW ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  1645. switch( uc.Shadow )
  1646. {
  1647. case Shadow_EnableInputNotify:
  1648. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  1649. SendMessage( GetDlgItem( hwnd , IDC_RADIO_CONTROL ) , BM_CLICK , 0 , 0 );
  1650. break;
  1651. case Shadow_EnableInputNoNotify:
  1652. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )FALSE , 0 );
  1653. SendMessage( GetDlgItem( hwnd , IDC_RADIO_CONTROL ) , BM_CLICK , 0 , 0 );
  1654. break;
  1655. case Shadow_EnableNoInputNotify:
  1656. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )TRUE , 0 );
  1657. SendMessage( GetDlgItem( hwnd , IDC_RADIO_WATCH ) , BM_CLICK , 0 , 0 );
  1658. break;
  1659. case Shadow_EnableNoInputNoNotify:
  1660. SendMessage( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , BM_SETCHECK , ( WPARAM )FALSE , 0 );
  1661. SendMessage( GetDlgItem( hwnd , IDC_RADIO_WATCH ) , BM_CLICK , 0 , 0 );
  1662. break;
  1663. }
  1664. m_wOldRad = ( WORD )( IsDlgButtonChecked( hwnd , IDC_RADIO_WATCH ) ? IDC_RADIO_WATCH : IDC_RADIO_CONTROL ) ;
  1665. }
  1666. m_bPersisted = TRUE;
  1667. return CDialogBase::OnInitDialog( hwnd , wp , lp );
  1668. }
  1669. BOOL CShadowDlg::OnDestroy( )
  1670. {
  1671. return CDialogBase::OnDestroy( );
  1672. }
  1673. //-------------------------------------------------------------------------------
  1674. // GetPropertySheetPage - each dialog object should be responsible for its own data
  1675. //-------------------------------------------------------------------------------
  1676. BOOL CShadowDlg::GetPropertySheetPage( PROPSHEETPAGE &psp )
  1677. {
  1678. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  1679. psp.dwSize = sizeof( PROPSHEETPAGE );
  1680. psp.dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
  1681. psp.hInstance = _Module.GetModuleInstance( );
  1682. psp.pszTemplate = MAKEINTRESOURCE( IDD_PAGE_SHADOW );
  1683. psp.lParam = (LPARAM)this;
  1684. psp.pfnCallback = CDialogBase::PageCallback;
  1685. psp.pfnDlgProc = CShadowDlg::DlgProc;
  1686. return TRUE;
  1687. }
  1688. //-------------------------------------------------------------------------------
  1689. // Basic control notification handler
  1690. //-------------------------------------------------------------------------------
  1691. void CShadowDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtl )
  1692. {
  1693. switch( wNotifyCode )
  1694. {
  1695. case BN_CLICKED:
  1696. if( wID == IDC_CHECK_SHADOW )
  1697. {
  1698. HWND hwnd = GetParent( hwndCtl );
  1699. BOOL bChecked = SendMessage( hwndCtl , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? TRUE : FALSE;
  1700. SendMessage( GetDlgItem( hwnd , IDC_CHECK_SHADOW ) , BM_SETCHECK , ( WPARAM )bChecked , 0 );
  1701. EnableWindow( GetDlgItem( hwnd , IDC_RADIO_WATCH ) , bChecked );
  1702. EnableWindow( GetDlgItem( hwnd , IDC_RADIO_CONTROL ) , bChecked );
  1703. EnableWindow( GetDlgItem( hwnd , IDC_CHECK_NOTIFY ) , bChecked );
  1704. EnableWindow( GetDlgItem( hwnd , IDC_STATIC_LEVELOFCTRL ) , bChecked );
  1705. //
  1706. // if neither radio buttons are selected force IDC_RADIO_CONTROL to be selected
  1707. //
  1708. if(
  1709. ( SendMessage( GetDlgItem( hwnd , IDC_RADIO_WATCH ) , BM_GETSTATE , 0 , 0 ) == BST_UNCHECKED )
  1710. &&
  1711. ( SendMessage( GetDlgItem( hwnd , IDC_RADIO_CONTROL ) , BM_GETSTATE , 0 , 0 ) == BST_UNCHECKED )
  1712. )
  1713. {
  1714. SendMessage( GetDlgItem( hwnd , IDC_RADIO_CONTROL ) , BM_SETCHECK , ( WPARAM )BST_CHECKED , 0 );
  1715. m_wOldRad = IDC_RADIO_CONTROL;
  1716. }
  1717. m_bPersisted = FALSE;
  1718. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  1719. }
  1720. else if( wID == IDC_RADIO_WATCH || wID == IDC_RADIO_CONTROL )
  1721. {
  1722. if( wID != m_wOldRad )
  1723. {
  1724. m_wOldRad = wID;
  1725. m_bPersisted = FALSE;
  1726. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  1727. }
  1728. }
  1729. else if( wID == IDC_CHECK_NOTIFY )
  1730. {
  1731. m_bPersisted = FALSE;
  1732. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  1733. }
  1734. break;
  1735. case ALN_APPLY:
  1736. //This is being removed for consinstency with the rest of MMC dialogs, even though it would
  1737. //make more sense to the user for Cancel to be disabled after applying the changes, since
  1738. //cancellation is not a real option at that point.
  1739. //SendMessage( GetParent( hwndCtl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  1740. break;
  1741. }
  1742. }
  1743. //-------------------------------------------------------------------------------
  1744. // PersisitSettings
  1745. //-------------------------------------------------------------------------------
  1746. BOOL CShadowDlg::PersistSettings( HWND hDlg )
  1747. {
  1748. DWORD dwStatus;
  1749. if( IsBadReadPtr( m_pUSht , sizeof( CTSUserSheet ) ) )
  1750. {
  1751. return FALSE;
  1752. }
  1753. USERCONFIG uc;
  1754. uc = m_pUSht->GetCurrentUserConfig( &dwStatus );
  1755. //
  1756. // Record all changes
  1757. //
  1758. if( SendMessage( GetDlgItem( hDlg , IDC_CHECK_SHADOW ) , BM_GETCHECK , 0 , 0 ) != BST_CHECKED )
  1759. {
  1760. uc.Shadow = Shadow_Disable;
  1761. }
  1762. else
  1763. {
  1764. BOOL bCheckNotify = (BOOL)SendMessage( GetDlgItem( hDlg , IDC_CHECK_NOTIFY ) , BM_GETCHECK , 0 , 0 );
  1765. BOOL bRadioControl = (BOOL)SendMessage( GetDlgItem( hDlg , IDC_RADIO_CONTROL ) , BM_GETCHECK , 0 , 0 );
  1766. if( bCheckNotify )
  1767. {
  1768. if( bRadioControl )
  1769. {
  1770. uc.Shadow = Shadow_EnableInputNotify;
  1771. }
  1772. else
  1773. {
  1774. uc.Shadow = Shadow_EnableNoInputNotify;
  1775. }
  1776. }
  1777. else
  1778. {
  1779. if( bRadioControl )
  1780. {
  1781. uc.Shadow = Shadow_EnableInputNoNotify;
  1782. }
  1783. else
  1784. {
  1785. uc.Shadow = Shadow_EnableNoInputNoNotify;
  1786. }
  1787. }
  1788. }
  1789. if( !m_pUSht->SetUserConfig( uc , &dwStatus ) )
  1790. {
  1791. ErrorMessage2( hDlg , dwStatus );
  1792. return TRUE;
  1793. }
  1794. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  1795. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  1796. return TRUE;
  1797. }
  1798. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  1799. CProfileDlg::CProfileDlg( CTSUserSheet *pUsh )
  1800. {
  1801. m_pUSht = pUsh;
  1802. m_wOldRadio = ( WORD )-1;
  1803. m_ncbxOld = -1;
  1804. }
  1805. //-------------------------------------------------------------------------------
  1806. // GetPropertySheetPage - each dialog object should be responsible for its own data
  1807. //-------------------------------------------------------------------------------
  1808. BOOL CProfileDlg::GetPropertySheetPage( PROPSHEETPAGE &psp )
  1809. {
  1810. ZeroMemory( &psp , sizeof( PROPSHEETPAGE ) );
  1811. psp.dwSize = sizeof( PROPSHEETPAGE );
  1812. psp.dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
  1813. psp.hInstance = _Module.GetModuleInstance( );
  1814. psp.pszTemplate = MAKEINTRESOURCE( IDD_PAGE_PROFILE );
  1815. psp.lParam = (LPARAM)this;
  1816. psp.pfnCallback = CDialogBase::PageCallback;
  1817. psp.pfnDlgProc = CProfileDlg::DlgProc;
  1818. return TRUE;
  1819. }
  1820. //-------------------------------------------------------------------------------
  1821. // CProfileDlg Dialog Page
  1822. // -- static methods lacks this ptr
  1823. //-------------------------------------------------------------------------------
  1824. INT_PTR CALLBACK CProfileDlg::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  1825. {
  1826. CProfileDlg *pDlg;
  1827. if( msg == WM_INITDIALOG )
  1828. {
  1829. CProfileDlg *pDlg = ( CProfileDlg * )( ( PROPSHEETPAGE *)lp )->lParam ;
  1830. SetWindowLongPtr( hwnd , DWLP_USER , ( LONG_PTR )pDlg );
  1831. if( !IsBadReadPtr( pDlg , sizeof( CProfileDlg ) ) )
  1832. {
  1833. pDlg->OnInitDialog( hwnd , wp , lp );
  1834. }
  1835. return 0;
  1836. }
  1837. else
  1838. {
  1839. pDlg = ( CProfileDlg * )GetWindowLongPtr( hwnd , DWLP_USER );
  1840. if( IsBadReadPtr( pDlg , sizeof( CProfileDlg ) ) )
  1841. {
  1842. return FALSE;
  1843. }
  1844. }
  1845. switch( msg )
  1846. {
  1847. case WM_NCDESTROY:
  1848. pDlg->OnDestroy( );
  1849. break;
  1850. case WM_COMMAND:
  1851. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  1852. break;
  1853. case WM_NOTIFY:
  1854. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );
  1855. case WM_HELP:
  1856. pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  1857. break;
  1858. case WM_RBUTTONUP:
  1859. {
  1860. POINT pt;
  1861. pt.x = LOWORD( lp );
  1862. pt.y = HIWORD( lp );
  1863. HWND hChild = ChildWindowFromPoint( hwnd , pt );
  1864. ClientToScreen( hwnd , &pt );
  1865. pDlg->OnContextMenu( hChild , pt );
  1866. }
  1867. break;
  1868. case WM_CONTEXTMENU:
  1869. {
  1870. POINT pt;
  1871. pt.x = LOWORD( lp );
  1872. pt.y = HIWORD( lp );
  1873. pDlg->OnContextMenu( ( HWND )wp , pt );
  1874. }
  1875. }
  1876. return 0;
  1877. }
  1878. //-------------------------------------------------------------------------------
  1879. // InitDialog for CProfileDlg
  1880. //-------------------------------------------------------------------------------
  1881. BOOL CProfileDlg::OnInitDialog( HWND hwnd , WPARAM wp , LPARAM lp )
  1882. {
  1883. TCHAR tchDrv[3];
  1884. DWORD dwStatus;
  1885. if( IsBadReadPtr( m_pUSht ,sizeof( CTSUserSheet ) ) )
  1886. {
  1887. return FALSE;
  1888. }
  1889. USERCONFIG uc;
  1890. uc = m_pUSht->GetCurrentUserConfig( &dwStatus );
  1891. if( dwStatus != ERROR_FILE_NOT_FOUND && dwStatus != ERROR_SUCCESS )
  1892. {
  1893. INT nId[ ] = {
  1894. IDC_CHECK_ALLOWLOGON,
  1895. IDC_COMBO_DRIVES,
  1896. IDC_EDIT_REMOTEPATH,
  1897. IDC_RADIO_REMOTE,
  1898. IDC_EDIT_LOCALPATH,
  1899. IDC_RADIO_LOCAL,
  1900. IDC_EDIT_USRPROFILE,
  1901. -1
  1902. };
  1903. for( int idx = 0; nId[ idx ] != -1 ; ++idx )
  1904. {
  1905. EnableWindow( GetDlgItem( hwnd , nId[ idx ] ) , FALSE );
  1906. }
  1907. ErrorMessage1( hwnd , dwStatus );
  1908. return FALSE;
  1909. }
  1910. SendMessage( GetDlgItem( hwnd , IDC_CHECK_ALLOWLOGON ) , BM_SETCHECK , ( WPARAM )( !uc.fLogonDisabled ) , 0 );
  1911. SendMessage( GetDlgItem( hwnd , IDC_EDIT_LOCALPATH ) , EM_SETLIMITTEXT , ( WPARAM )DIRECTORY_LENGTH , 0 );
  1912. SendMessage( GetDlgItem( hwnd , IDC_EDIT_REMOTEPATH ) , EM_SETLIMITTEXT , ( WPARAM )DIRECTORY_LENGTH , 0 );
  1913. SendMessage( GetDlgItem( hwnd , IDC_EDIT_USRPROFILE ) , EM_SETLIMITTEXT , ( WPARAM )DIRECTORY_LENGTH , 0 );
  1914. for( TCHAR DrvLetter = 'C'; DrvLetter <= 'Z'; DrvLetter++ )
  1915. {
  1916. tchDrv[0] = DrvLetter;
  1917. tchDrv[1] = ':';
  1918. tchDrv[2] = 0;
  1919. SendMessage( GetDlgItem( hwnd , IDC_COMBO_DRIVES ) , CB_ADDSTRING , 0 , ( LPARAM )&tchDrv[ 0 ] );
  1920. }
  1921. if( PathIsUNC( uc.WFHomeDir ) )
  1922. {
  1923. ODS( L"TSUSEREX: Path is UNC\n" );
  1924. CharUpper( &uc.WFHomeDirDrive[0] );
  1925. if( uc.WFHomeDirDrive[ 0 ] >= 'C' && uc.WFHomeDirDrive[ 0 ] <= 'Z' )
  1926. {
  1927. m_ncbxOld = (int)SendMessage( GetDlgItem( hwnd , IDC_COMBO_DRIVES ) , CB_SETCURSEL , ( WPARAM )( uc.WFHomeDirDrive[ 0 ] - 'C' ) , 0 );
  1928. }
  1929. else
  1930. {
  1931. // default it to Z drive
  1932. m_ncbxOld = (int)SendMessage( GetDlgItem( hwnd , IDC_COMBO_DRIVES ) , CB_SETCURSEL , ( WPARAM )( 'Z' - 'C' ) , 0 );
  1933. }
  1934. SetWindowText( GetDlgItem( hwnd , IDC_EDIT_REMOTEPATH ) , uc.WFHomeDir );
  1935. //SendMessage( GetDlgItem( hwnd , IDC_RADIO_REMOTE ) , BM_CLICK , 0 , 0 );
  1936. SendMessage( GetDlgItem( hwnd , IDC_RADIO_REMOTE ) , BM_SETCHECK , ( WPARAM )BST_CHECKED , 0 );
  1937. SendMessage( GetDlgItem( hwnd , IDC_RADIO_LOCAL ) , BM_SETCHECK , ( WPARAM )BST_UNCHECKED , 0 );
  1938. m_wOldRadio = IDC_RADIO_REMOTE;
  1939. }
  1940. else
  1941. {
  1942. ODS( L"TSUSEREX: Path is Local\n" );
  1943. SendMessage( GetDlgItem( hwnd , IDC_EDIT_LOCALPATH ) , WM_SETTEXT , 0 , ( LPARAM )&uc.WFHomeDir[ 0 ] );
  1944. // SendMessage( GetDlgItem( hwnd , IDC_RADIO_LOCAL ) , BM_CLICK , 0 , 0 );
  1945. SendMessage( GetDlgItem( hwnd , IDC_RADIO_LOCAL ) , BM_SETCHECK , ( WPARAM )BST_CHECKED , 0 );
  1946. SendMessage( GetDlgItem( hwnd , IDC_RADIO_REMOTE ) , BM_SETCHECK , ( WPARAM )BST_UNCHECKED , 0 );
  1947. m_wOldRadio = IDC_RADIO_LOCAL;
  1948. }
  1949. EnableRemoteHomeDirectory( hwnd , ( BOOL )( m_wOldRadio == IDC_RADIO_REMOTE ) );
  1950. SendMessage( GetDlgItem( hwnd , IDC_EDIT_USRPROFILE ) , WM_SETTEXT , 0 , ( LPARAM )&uc.WFProfilePath[ 0 ] );
  1951. m_bPersisted = TRUE;
  1952. m_bTSHomeFolderChanged = FALSE;
  1953. return CDialogBase::OnInitDialog( hwnd , wp , lp );
  1954. }
  1955. //-------------------------------------------------------------------------------
  1956. // EnableRemoteHomeDirectory -- basically enables or disables dlg controls
  1957. //-------------------------------------------------------------------------------
  1958. BOOL CProfileDlg::EnableRemoteHomeDirectory( HWND hwnd , BOOL bHDMR )
  1959. {
  1960. //
  1961. // Local home directory
  1962. //
  1963. EnableWindow( GetDlgItem( hwnd , IDC_EDIT_LOCALPATH ) , !bHDMR );
  1964. //
  1965. // Network'd home directory
  1966. //
  1967. EnableWindow( GetDlgItem( hwnd , IDC_COMBO_DRIVES ) , bHDMR );
  1968. EnableWindow( GetDlgItem( hwnd , IDC_EDIT_REMOTEPATH ) , bHDMR );
  1969. return TRUE;
  1970. }
  1971. BOOL CProfileDlg::OnDestroy( )
  1972. {
  1973. return CDialogBase::OnDestroy( );
  1974. }
  1975. //-------------------------------------------------------------------------------
  1976. // Basic control notification handler
  1977. //-------------------------------------------------------------------------------
  1978. void CProfileDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtl )
  1979. {
  1980. switch( wNotifyCode )
  1981. {
  1982. case EN_CHANGE:
  1983. m_bPersisted = FALSE;
  1984. if( wID == IDC_EDIT_REMOTEPATH || wID == IDC_EDIT_LOCALPATH )
  1985. {
  1986. ODS( L"EN_CHANGE m_bTSHomeFolderChanged = TRUE;\n" );
  1987. m_bTSHomeFolderChanged = TRUE;
  1988. }
  1989. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  1990. break;
  1991. //case CBN_DROPDOWN:
  1992. case CBN_SELCHANGE:
  1993. {
  1994. int nCurSel = (int)SendMessage( hwndCtl , CB_GETCURSEL , 0 , 0 );
  1995. if( m_ncbxOld != nCurSel )
  1996. {
  1997. m_ncbxOld = nCurSel;
  1998. ODS( L"CBN_SELCHANGE m_bTSHomeFolderChanged = TRUE;\n" );
  1999. m_bTSHomeFolderChanged = TRUE;
  2000. m_bPersisted = FALSE;
  2001. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  2002. }
  2003. }
  2004. break;
  2005. case BN_CLICKED:
  2006. if( wID == IDC_RADIO_REMOTE || wID == IDC_RADIO_LOCAL )
  2007. {
  2008. if( wID != m_wOldRadio )
  2009. {
  2010. EnableRemoteHomeDirectory( GetParent( hwndCtl ) , ( BOOL )( wID == IDC_RADIO_REMOTE ) );
  2011. m_wOldRadio = wID;
  2012. m_bPersisted = FALSE;
  2013. ODS( L"Setting m_bTSHomeFolderChanged to true\n" );
  2014. m_bTSHomeFolderChanged = TRUE;
  2015. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  2016. }
  2017. if( wID == IDC_RADIO_LOCAL )
  2018. {
  2019. SetFocus( GetDlgItem( GetParent( hwndCtl ) , IDC_EDIT_LOCALPATH ) );
  2020. SendMessage( GetDlgItem( GetParent( hwndCtl ) , IDC_EDIT_LOCALPATH ) , EM_SETSEL , ( WPARAM )0 , ( LPARAM )-1 );
  2021. }
  2022. else if( wID == IDC_RADIO_REMOTE )
  2023. {
  2024. if( SendMessage( GetDlgItem( GetParent( hwndCtl ) , IDC_COMBO_DRIVES ) ,
  2025. CB_GETCURSEL,
  2026. 0,
  2027. 0 ) == CB_ERR )
  2028. {
  2029. SendMessage( GetDlgItem( GetParent( hwndCtl ) , IDC_COMBO_DRIVES ) ,
  2030. CB_SETCURSEL,
  2031. ( WPARAM )( 'Z' - 'C' ),
  2032. 0 );
  2033. }
  2034. SetFocus( GetDlgItem( GetParent( hwndCtl ) , IDC_COMBO_DRIVES ) );
  2035. }
  2036. }
  2037. else if( wID == IDC_CHECK_ALLOWLOGON )
  2038. {
  2039. m_bPersisted = FALSE;
  2040. SendMessage( GetParent( GetParent( hwndCtl ) ) , PSM_CHANGED , ( WPARAM )GetParent( hwndCtl ) , 0 );
  2041. }
  2042. break;
  2043. case ALN_APPLY:
  2044. //This is being removed for consinstency with the rest of MMC dialogs, even though it would
  2045. //make more sense to the user for Cancel to be disabled after applying the changes, since
  2046. //cancellation is not a real option at that point.
  2047. //SendMessage( GetParent( hwndCtl ) , PSM_CANCELTOCLOSE , 0 , 0 );
  2048. break;
  2049. }
  2050. }
  2051. //-------------------------------------------------------------------------------
  2052. // PersistSettings -- remember TRUE is bad FALSE is good
  2053. //-------------------------------------------------------------------------------
  2054. BOOL CProfileDlg::PersistSettings( HWND hDlg )
  2055. {
  2056. BOOL bRet = TRUE;;
  2057. DWORD dwStatus;
  2058. if( IsBadReadPtr( m_pUSht , sizeof( CTSUserSheet ) ) )
  2059. {
  2060. return TRUE;
  2061. }
  2062. USERCONFIG uc;
  2063. uc = m_pUSht->GetCurrentUserConfig( &dwStatus );
  2064. //
  2065. // expensive but necessary id34393
  2066. //
  2067. if( !m_pUSht->SetUserConfig( uc , &dwStatus ) )
  2068. {
  2069. ErrorMessage2( hDlg , dwStatus );
  2070. m_bTSHomeFolderChanged = FALSE;
  2071. return TRUE;
  2072. }
  2073. //
  2074. // Determine whether to enable user to logon to a terminal server
  2075. //
  2076. uc.fLogonDisabled = SendMessage( GetDlgItem( hDlg , IDC_CHECK_ALLOWLOGON ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED ? FALSE : TRUE;
  2077. //
  2078. // Profile path is under the admin discretion
  2079. //
  2080. SetWTSProfilePath( hDlg , uc );
  2081. //
  2082. // Parse and flag corrupt data
  2083. //
  2084. if( m_bTSHomeFolderChanged )
  2085. {
  2086. ODS( L"Persisting home folder settings\n" );
  2087. if( SendMessage( GetDlgItem( hDlg , IDC_RADIO_LOCAL ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED )
  2088. {
  2089. bRet = SetWTSLocalPath( hDlg , uc );
  2090. // Set WFHomeDirDrive to NULL because Home folder is a Local folder
  2091. wcscpy(uc.WFHomeDirDrive, L"\0");
  2092. }
  2093. else
  2094. {
  2095. bRet = SetWTSRemotePath( hDlg , uc );
  2096. }
  2097. m_bTSHomeFolderChanged = FALSE;
  2098. }
  2099. if( bRet )
  2100. {
  2101. if( !m_pUSht->SetUserConfig( uc , &dwStatus ) )
  2102. {
  2103. ErrorMessage2( hDlg , dwStatus );
  2104. return TRUE;
  2105. }
  2106. PostMessage( hDlg , WM_COMMAND , MAKELPARAM( 0 , ALN_APPLY ) , ( LPARAM )hDlg );
  2107. SendMessage( GetParent( hDlg ) , PSM_UNCHANGED , ( WPARAM )hDlg , 0 );
  2108. }
  2109. return bRet;
  2110. }
  2111. //-------------------------------------------------------------------------------
  2112. // IsValidSettings doesnot persist the information
  2113. //-------------------------------------------------------------------------------
  2114. BOOL CProfileDlg::IsValidSettings( HWND hDlg )
  2115. {
  2116. BOOL bRet = TRUE;
  2117. //
  2118. // Parse and flag corrupt data
  2119. //
  2120. if( m_bTSHomeFolderChanged )
  2121. {
  2122. ODS( L"Checking validity of home folders\n" );
  2123. if( SendMessage( GetDlgItem( hDlg , IDC_RADIO_LOCAL ) , BM_GETCHECK , 0 , 0 ) == BST_CHECKED )
  2124. {
  2125. bRet = IsLocalPathValid( hDlg );
  2126. }
  2127. else
  2128. {
  2129. bRet = IsRemotePathValid( hDlg );
  2130. }
  2131. }
  2132. return bRet;
  2133. }
  2134. //-------------------------------------------------------------------------------
  2135. // SetWTSProfilePath
  2136. //-------------------------------------------------------------------------------
  2137. BOOL CProfileDlg::SetWTSProfilePath( HWND hDlg , USERCONFIG& uc )
  2138. {
  2139. //
  2140. // It looks like we don't care what the user enters
  2141. // I'm borrowing the behavior from the current usrmgr profile page
  2142. //
  2143. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_USRPROFILE ) , uc.WFProfilePath , sizeof( uc.WFProfilePath ) / sizeof( TCHAR ) );
  2144. ExpandUserName( uc.WFProfilePath );
  2145. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_USRPROFILE ) , uc.WFProfilePath );
  2146. return TRUE;
  2147. }
  2148. // Create all the folders required, up to and including the leaf folder.
  2149. // Path is expected to be of the form \\server\share\...
  2150. HRESULT CProfileDlg::CreateRemoteFolder(LPCTSTR path)
  2151. {
  2152. HRESULT hr = S_OK;
  2153. LPTSTR current = (LPTSTR)path;
  2154. DWORD dwError;
  2155. //Find the first whack after the 1st 2
  2156. current = wcschr(current + 2, L'\\');
  2157. //Now find the next one. We should be at the end of the share name
  2158. current = wcschr(current + 1, L'\\');
  2159. //Now find the next one. We should be at the end of the drive name
  2160. current = wcschr(current + 1, L'\\');
  2161. while (SUCCEEDED(hr))
  2162. {
  2163. //Mark the trailing backslash as the end of the string. This
  2164. //makes path point to a truncated path (containing only the folder
  2165. //names we have walked thru so far).
  2166. if (current)
  2167. *current = 0;
  2168. // create a secure ACL'd directory if it already exists it will
  2169. // return a success
  2170. if (!CreateSecureDir((LPTSTR)path , &dwError))
  2171. {
  2172. ODS(L"CreateSecureDir failed\n");
  2173. hr = E_FAIL;
  2174. }
  2175. if (current)
  2176. {
  2177. //Replace the original trailing backslash, and move on to the
  2178. //next backslash after that.
  2179. *current = L'\\';
  2180. current = wcschr(current + 1, L'\\');
  2181. }
  2182. else
  2183. {
  2184. //No more folders are on the path. We're done.
  2185. break;
  2186. }
  2187. }
  2188. return hr;
  2189. }
  2190. BOOL CProfileDlg::IsLocalComputer(WCHAR* pwchMachinename)
  2191. {
  2192. BOOL bLocal = FALSE;
  2193. WCHAR pwchComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  2194. DWORD dwLen = sizeof(pwchComputerName)/sizeof(WCHAR);
  2195. if (GetComputerNameEx(ComputerNameNetBIOS, pwchComputerName, &dwLen))
  2196. {
  2197. if (_wcsicmp(pwchComputerName, pwchMachinename) == 0)
  2198. bLocal = TRUE;
  2199. }
  2200. if (GetComputerNameEx(ComputerNameDnsFullyQualified, pwchComputerName, &dwLen))
  2201. {
  2202. if (_wcsicmp(pwchComputerName, pwchMachinename) == 0)
  2203. bLocal = TRUE;
  2204. }
  2205. return bLocal;
  2206. }
  2207. //Put the absolute path into the form \\machinename\drive$\path
  2208. BOOL CProfileDlg::CreateSystemPath(WCHAR* chPath)
  2209. {
  2210. WCHAR* pstrMachinename = NULL;
  2211. if (m_pUSht->GetServer(&pstrMachinename))
  2212. {
  2213. if (pstrMachinename)
  2214. {
  2215. //Start constructing the system path
  2216. WCHAR chSystemPath[MAX_PATH];
  2217. wcscpy(chSystemPath, L"\\\\");
  2218. wcsncat(chSystemPath, pstrMachinename, MAX_PATH - wcslen(chSystemPath) - 1);
  2219. //Now set the local flag accordingly
  2220. BOOL bLocalMachine = IsLocalComputer(pstrMachinename);
  2221. //We've got no use for this anymore
  2222. if (pstrMachinename)
  2223. delete[] pstrMachinename;
  2224. if (bLocalMachine)
  2225. {
  2226. DWORD dwErr = 0;
  2227. return createdir(chPath, FALSE, &dwErr);
  2228. }
  2229. //It's not local so continue contructing the path
  2230. wcsncat(chSystemPath, L"\\", MAX_PATH - wcslen(chSystemPath) - 1);
  2231. //The path should be valid by this point, but we might
  2232. //as well verify that for ourselves
  2233. if ((wcslen(chPath) >= 4) &&
  2234. (IsCharAlpha(chPath[0])) &&
  2235. (chPath[1] == L':') &&
  2236. (chPath[2] == L'\\') &&
  2237. (IsCharAlpha(chPath[3])))
  2238. {
  2239. size_t nCurrentLength = wcslen(chSystemPath);
  2240. if (nCurrentLength < (MAX_PATH - 2))
  2241. {
  2242. chSystemPath[nCurrentLength] = chPath[0];
  2243. chSystemPath[nCurrentLength + 1] = L'\0';
  2244. wcsncat(chSystemPath, L"$", MAX_PATH - wcslen(chSystemPath) - 1);
  2245. wcsncat(chSystemPath, chPath + 2, MAX_PATH - wcslen(chSystemPath) - 1);
  2246. }
  2247. //Now that the system path is constructed, let's create the folder
  2248. return SUCCEEDED(CreateRemoteFolder(chSystemPath));
  2249. }
  2250. }
  2251. }
  2252. return FALSE;
  2253. }
  2254. //-------------------------------------------------------------------------------
  2255. // IsLocalPathValid
  2256. //-------------------------------------------------------------------------------
  2257. BOOL CProfileDlg::IsLocalPathValid( HWND hDlg )
  2258. {
  2259. LPVOID tchBuf = NULL;
  2260. TCHAR tchErr[ MAX_PATH ] = { 0 };
  2261. TCHAR tchErrTitle[ 80 ]= { 0 };
  2262. TCHAR tchPath[ MAX_PATH ]= { 0 };
  2263. INT_PTR dw = ( INT_PTR )&tchPath[0];
  2264. if( SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOCALPATH ) , WM_GETTEXT , sizeof( tchPath ) / sizeof( TCHAR ) , ( LPARAM )&tchPath[ 0 ] ) > 0 )
  2265. {
  2266. ExpandUserName( tchPath );
  2267. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_LOCALPATH ) , tchPath );
  2268. if( !IsPathValid( tchPath , FALSE ) )
  2269. {
  2270. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_PATH , tchErr , sizeof( tchErr ) / sizeof( TCHAR ) );
  2271. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , sizeof( tchErrTitle ) / sizeof( TCHAR ) );
  2272. FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  2273. tchErr , 0 , 0 , (WCHAR*)&tchBuf , sizeof( tchErr ) / sizeof( TCHAR ) , ( va_list * )&dw );
  2274. if (tchBuf)
  2275. {
  2276. MessageBox(hDlg, (WCHAR*)tchBuf, tchErrTitle, MB_OK | MB_ICONERROR);
  2277. LocalFree(tchBuf);
  2278. }
  2279. else
  2280. MessageBox(hDlg, tchErr, tchErrTitle, MB_OK | MB_ICONERROR);
  2281. return FALSE;
  2282. }
  2283. }
  2284. return TRUE;
  2285. }
  2286. //-------------------------------------------------------------------------------
  2287. // SetWTSLocalPath - copies the contents over - IsPathValid would have return
  2288. // true inorder for us to get here!
  2289. //-------------------------------------------------------------------------------
  2290. BOOL CProfileDlg::SetWTSLocalPath( HWND hDlg , USERCONFIG& uc )
  2291. {
  2292. SendMessage( GetDlgItem( hDlg , IDC_EDIT_LOCALPATH ) , WM_GETTEXT , sizeof( uc.WFHomeDir ) / sizeof( TCHAR ) , ( LPARAM )&uc.WFHomeDir[ 0 ] );
  2293. if (!m_pUSht->GetDSAType())
  2294. {
  2295. //We won't return the result from this because,
  2296. //even if the path isn't created, the setting
  2297. //may still be persisted and the admin can add
  2298. //the directory after the fact
  2299. CreateSystemPath(uc.WFHomeDir);
  2300. }
  2301. return TRUE;
  2302. }
  2303. //-------------------------------------------------------------------------------
  2304. // IsRemotePathValid - verifies UNC is correct
  2305. //-------------------------------------------------------------------------------
  2306. BOOL CProfileDlg::IsRemotePathValid( HWND hDlg )
  2307. {
  2308. TCHAR tchErr1[ 768 ] = { 0 };
  2309. TCHAR tchError[ 768 ] = { 0 };
  2310. TCHAR tchHomeDir[ MAX_PATH ] = { 0 };
  2311. if( GetWindowText( GetDlgItem( hDlg , IDC_EDIT_REMOTEPATH ) , tchHomeDir , sizeof( tchHomeDir ) / sizeof( TCHAR ) ) > 0 )
  2312. {
  2313. ExpandUserName( tchHomeDir );
  2314. SetWindowText( GetDlgItem( hDlg , IDC_EDIT_REMOTEPATH ) , tchHomeDir );
  2315. if( !IsPathValid( tchHomeDir , TRUE ) )
  2316. {
  2317. if( LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_REMOTEPATH , tchErr1 , sizeof( tchErr1 ) / sizeof( TCHAR ) ) > 0 )
  2318. {
  2319. INT_PTR dw = ( INT_PTR )&tchHomeDir[ 0 ];
  2320. FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, tchErr1 , 0 , 0 , tchError , sizeof( tchError ) / sizeof( TCHAR ) , ( va_list * )&dw );
  2321. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErr1 , sizeof( tchErr1 ) / sizeof( TCHAR ) );
  2322. MessageBox( hDlg , tchError , tchErr1 , MB_OK | MB_ICONERROR );
  2323. }
  2324. return FALSE;
  2325. }
  2326. }
  2327. else
  2328. {
  2329. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_NETPATH , tchError , sizeof( tchError ) / sizeof( TCHAR ) );
  2330. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErr1 , sizeof( tchErr1 ) / sizeof( TCHAR ) );
  2331. MessageBox( hDlg , tchError , tchErr1 , MB_OK | MB_ICONERROR );
  2332. return FALSE;
  2333. }
  2334. return TRUE;
  2335. }
  2336. //-------------------------------------------------------------------------------
  2337. // SetWTSRemotePath - IsRemotePathValid must return TRUE in order to get here
  2338. //-------------------------------------------------------------------------------
  2339. BOOL CProfileDlg::SetWTSRemotePath( HWND hDlg , USERCONFIG& uc )
  2340. {
  2341. TCHAR tchErr1[ 768 ] = { 0 };
  2342. TCHAR tchError[ 768 ] = { 0 };
  2343. GetWindowText( GetDlgItem( hDlg , IDC_EDIT_REMOTEPATH ) , uc.WFHomeDir , sizeof( uc.WFHomeDir ) / sizeof( TCHAR ) );
  2344. if( GetWindowText( GetDlgItem( hDlg , IDC_COMBO_DRIVES ) , uc.WFHomeDirDrive , sizeof( uc.WFHomeDirDrive ) / sizeof( TCHAR ) ) == 0 )
  2345. {
  2346. SendMessage( GetDlgItem( hDlg , IDC_COMBO_DRIVES ) , CB_GETLBTEXT , 0 , ( LPARAM )&uc.WFHomeDirDrive );
  2347. }
  2348. DWORD dwErr = 0;
  2349. if( !createdir( uc.WFHomeDir , TRUE , &dwErr ) )
  2350. {
  2351. if( dwErr != 0 )
  2352. {
  2353. UINT rId;
  2354. switch( dwErr )
  2355. {
  2356. case ERROR_ALREADY_EXISTS:
  2357. case ERROR_LOGON_FAILURE:
  2358. case ERROR_PATH_NOT_FOUND:
  2359. {
  2360. rId = ( ERROR_ALREADY_EXISTS == dwErr) ?
  2361. IDS_HOME_DIR_EXISTS :
  2362. ( ERROR_PATH_NOT_FOUND == dwErr ) ?
  2363. IDS_HOME_DIR_CREATE_FAILED :
  2364. IDS_HOME_DIR_CREATE_NO_ACCESS;
  2365. LoadString( _Module.GetResourceInstance( ) , rId , tchErr1 , sizeof( tchErr1 ) / sizeof( TCHAR ) );
  2366. wsprintf( tchError , tchErr1 , uc.WFHomeDir );
  2367. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErr1 , sizeof( tchErr1 ) / sizeof( TCHAR ) );
  2368. MessageBox( hDlg , tchError , tchErr1 , MB_OK | MB_ICONERROR );
  2369. }
  2370. break;
  2371. default:
  2372. xxErrorMessage( hDlg , dwErr , IDS_ERR_CREATE_DIR );
  2373. }
  2374. }
  2375. }
  2376. // uc.fHomeDirectoryMapRoot = TRUE;
  2377. return TRUE;
  2378. }
  2379. //-------------------------------------------------------------------------------
  2380. // This is cool - I_NetPathType really does a lot of work for us
  2381. //-------------------------------------------------------------------------------
  2382. BOOL CProfileDlg::IsPathValid( LPTSTR pszPath , BOOL bUnc )
  2383. {
  2384. DWORD dwRetflags;
  2385. if( I_NetPathType( NULL, pszPath, &dwRetflags, 0) != NERR_Success )
  2386. return FALSE;
  2387. if( !bUnc )
  2388. return ((dwRetflags == ITYPE_PATH_ABSD) ? TRUE : FALSE);
  2389. return ((dwRetflags == ITYPE_UNC) ? TRUE : FALSE);
  2390. }
  2391. //-------------------------------------------------------------------------------
  2392. // If the string contains %username% expand it to the current user.
  2393. //-------------------------------------------------------------------------------
  2394. void CProfileDlg::ExpandUserName( LPTSTR szPath )
  2395. {
  2396. TCHAR tchSubPath[ MAX_PATH];
  2397. TCHAR szUserName[ 40 ];
  2398. if( szPath == NULL )
  2399. {
  2400. return;
  2401. }
  2402. // remove any leading or trailing spaces
  2403. TCHAR tchTrim[] = TEXT( " " );
  2404. StrTrim( szPath , tchTrim );
  2405. int nSz = LoadString( _Module.GetResourceInstance( ) , IDS_USERNAME , szUserName , sizeof( szUserName ) / sizeof( TCHAR ) );
  2406. //CharLowerBuff( szPath , lstrlen( szPath ) );
  2407. // Find %username%
  2408. LPTSTR pFound = StrStrI( szPath , szUserName ); //_tcsstr( szPath , szUserName );
  2409. if( pFound != NULL )
  2410. {
  2411. INT_PTR nPos = ( INT_PTR )( pFound - szPath );
  2412. lstrcpy( tchSubPath , ( szPath + nPos + nSz ) );
  2413. szPath[ nPos ] = 0;
  2414. lstrcat( szPath , m_pUSht->GetUserName() );
  2415. lstrcat( szPath , tchSubPath );
  2416. }
  2417. }
  2418. //-------------------------------------------------------------------------------
  2419. // Removing decimal entries
  2420. //-------------------------------------------------------------------------------
  2421. LRESULT CTimeOutDlg::ParseDurationEntry( LPTSTR pszTime , PULONG pTime )
  2422. {
  2423. TCHAR tchNoTimeout[ 80 ];
  2424. LPTSTR pszTemp = pszTime;
  2425. UINT uDec = 0;
  2426. BOOL bSetDay = FALSE;
  2427. BOOL bSetHour = FALSE;
  2428. BOOL bSetMin = FALSE;
  2429. BOOL bEOL = FALSE;
  2430. BOOL bHasDigit= FALSE;
  2431. *pTime = 0;
  2432. LoadString( _Module.GetResourceInstance( ) , IDS_NOTIMEOUT , tchNoTimeout , sizeof( tchNoTimeout ) / sizeof( TCHAR ) );
  2433. if( lstrcmpi( pszTime , tchNoTimeout ) == 0 )
  2434. {
  2435. // *pTime = 0;
  2436. return E_SUCCESS;
  2437. }
  2438. while( !bEOL )
  2439. {
  2440. // remove leading white spaces
  2441. while( *pszTemp == L' ' )
  2442. {
  2443. pszTemp++;
  2444. }
  2445. while( *pszTemp )
  2446. {
  2447. if( !iswdigit( *pszTemp ) )
  2448. {
  2449. if( !bHasDigit )
  2450. {
  2451. return E_PARSE_MISSING_DIGITS;
  2452. }
  2453. break;
  2454. }
  2455. // check for overflow
  2456. if( uDec >= 1000000000 )
  2457. {
  2458. return E_PARSE_VALUEOVERFLOW ;
  2459. }
  2460. uDec *= 10;
  2461. uDec += ( *pszTemp - '0' );
  2462. if( !bHasDigit )
  2463. {
  2464. bHasDigit = TRUE;
  2465. }
  2466. pszTemp++;
  2467. }
  2468. // remove intermediate white spaces
  2469. while( *pszTemp == L' ' )
  2470. {
  2471. pszTemp++;
  2472. }
  2473. if( *pszTemp != NULL )
  2474. {
  2475. // Get next token
  2476. TCHAR tchToken[ 80 ];
  2477. pszTemp = GetNextToken( pszTemp , tchToken );
  2478. if( IsToken( tchToken , TOKEN_DAY ) )
  2479. {
  2480. if( !bSetDay )
  2481. {
  2482. *pTime += uDec * 1440;
  2483. bSetDay = TRUE;
  2484. }
  2485. }
  2486. else if( IsToken( tchToken , TOKEN_HOUR ) )
  2487. {
  2488. if( !bSetHour )
  2489. {
  2490. *pTime += uDec * 60;
  2491. bSetHour = TRUE;
  2492. }
  2493. }
  2494. else if( IsToken( tchToken , TOKEN_MINUTE ) )
  2495. {
  2496. if( !bSetMin )
  2497. {
  2498. *pTime += uDec;
  2499. bSetMin = TRUE;
  2500. }
  2501. }
  2502. else
  2503. {
  2504. return E_PARSE_INVALID;
  2505. }
  2506. }
  2507. else
  2508. {
  2509. if( !bSetHour )
  2510. {
  2511. *pTime += uDec * 60;
  2512. }
  2513. bEOL = TRUE;
  2514. }
  2515. uDec = 0;
  2516. bHasDigit = FALSE;
  2517. }
  2518. return E_SUCCESS;
  2519. }
  2520. //-------------------------------------------------------------------------------
  2521. // replacing older api
  2522. //-------------------------------------------------------------------------------
  2523. BOOL CTimeOutDlg::ConvertToDuration( ULONG ulTime , LPTSTR pszDuration )
  2524. {
  2525. // TCHAR dw[] = L"dhm";
  2526. TCHAR tchTimeUnit[ 40 ];
  2527. TCHAR tchTimeFormat[ 40 ];
  2528. TCHAR tchOutput[ 80 ];
  2529. ASSERT_( ulTime != 0 );
  2530. int iHour = ( ulTime / 60 );
  2531. int iDays = iHour / 24;
  2532. int iMinute = ulTime % 60;
  2533. // Resolve format
  2534. tchOutput[0] = 0;
  2535. if( iDays > 0 )
  2536. {
  2537. if( iDays == 1 )
  2538. {
  2539. LoadString( _Module.GetResourceInstance( ) , IDS_DAY , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  2540. }
  2541. else
  2542. {
  2543. LoadString( _Module.GetResourceInstance( ) , IDS_DAYS , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  2544. }
  2545. iHour = iHour % 24;
  2546. wsprintf( tchTimeFormat , L"%d %s", iDays , tchTimeUnit );
  2547. lstrcat( tchOutput , tchTimeFormat );
  2548. lstrcat( tchOutput , L" " );
  2549. }
  2550. if( iHour > 0 )
  2551. {
  2552. if( iHour == 1 )
  2553. {
  2554. LoadString( _Module.GetResourceInstance( ) , IDS_HOUR , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  2555. }
  2556. else
  2557. {
  2558. LoadString( _Module.GetResourceInstance( ) , IDS_HOURS , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  2559. }
  2560. wsprintf( tchTimeFormat , L"%d %s", iHour , tchTimeUnit );
  2561. lstrcat( tchOutput , tchTimeFormat );
  2562. lstrcat( tchOutput , L" " );
  2563. }
  2564. if( iMinute > 0 )
  2565. {
  2566. if( iMinute == 1 )
  2567. {
  2568. LoadString( _Module.GetResourceInstance( ) , IDS_MINUTE , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  2569. }
  2570. else
  2571. {
  2572. LoadString( _Module.GetResourceInstance( ) , IDS_MINUTES , tchTimeUnit , sizeof( tchTimeUnit ) / sizeof( TCHAR ) );
  2573. }
  2574. wsprintf( tchTimeFormat , L"%d %s", iMinute , tchTimeUnit );
  2575. lstrcat( tchOutput , tchTimeFormat );
  2576. lstrcat( tchOutput , L" " );
  2577. }
  2578. lstrcpy( pszDuration , tchOutput );
  2579. return TRUE;
  2580. }
  2581. //-------------------------------------------------------------------------------
  2582. BOOL CTimeOutDlg::DoesContainDigits( LPTSTR pszString )
  2583. {
  2584. while( *pszString )
  2585. {
  2586. if( *pszString != L' ')
  2587. {
  2588. if( iswdigit( *pszString ) )
  2589. {
  2590. return TRUE;
  2591. }
  2592. else
  2593. {
  2594. return FALSE;
  2595. }
  2596. pszString++;
  2597. }
  2598. }
  2599. return FALSE;
  2600. }
  2601. //-------------------------------------------------------------------------------
  2602. TCHAR * GetNextToken( TCHAR *pszString , TCHAR *tchToken )
  2603. {
  2604. while( *pszString )
  2605. {
  2606. if( IsCharAlpha( *pszString ) )
  2607. {
  2608. *tchToken = *pszString;
  2609. }
  2610. else
  2611. {
  2612. break;
  2613. }
  2614. tchToken++;
  2615. pszString++;
  2616. }
  2617. *tchToken = '\0';
  2618. return pszString;
  2619. }
  2620. //-------------------------------------------------------------------------------
  2621. void ErrorMessage1( HWND hParent , DWORD dwStatus )
  2622. {
  2623. xxErrorMessage( hParent , dwStatus , IDS_TSGETPROPSFAILED );
  2624. }
  2625. //-------------------------------------------------------------------------------
  2626. void ErrorMessage2( HWND hParent , DWORD dwStatus )
  2627. {
  2628. xxErrorMessage( hParent , dwStatus , IDS_TSOPSFAILED );
  2629. }
  2630. //-------------------------------------------------------------------------------
  2631. void xxErrorMessage( HWND hParent , DWORD dwStatus , UINT nResID )
  2632. {
  2633. LPTSTR pBuffer = NULL;
  2634. TCHAR tchBuffer[ 256 ];
  2635. TCHAR tchErr[ 128 ];
  2636. TCHAR tchTitle[ 80 ];
  2637. LoadString( _Module.GetModuleInstance( ) , nResID , tchErr , sizeof( tchErr ) / sizeof( TCHAR ) );
  2638. LoadString( _Module.GetModuleInstance( ) , IDS_TSGETPROPTITLE , tchTitle , sizeof( tchTitle ) / sizeof( TCHAR ) );
  2639. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  2640. FORMAT_MESSAGE_FROM_SYSTEM,
  2641. NULL, //ignored
  2642. dwStatus , //message ID
  2643. MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), //message language
  2644. (LPTSTR)&pBuffer, //address of buffer pointer
  2645. 0, //minimum buffer size
  2646. NULL); //no other arguments
  2647. wsprintf( tchBuffer , tchErr , pBuffer );
  2648. ::MessageBox( hParent , tchBuffer , tchTitle , MB_OK | MB_ICONERROR );
  2649. if( pBuffer != NULL )
  2650. {
  2651. LocalFree( pBuffer );
  2652. }
  2653. }
  2654. #if 0
  2655. //-------------------------------------------------------------------------------
  2656. NTSTATUS GetDomainName( PWCHAR ServerNamePtr, // name of server to get domain of
  2657. LPTSTR DomainNamePtr // alloc and set ptr (free with NetApiBufferFree)
  2658. )
  2659. /*++
  2660. Routine Description:
  2661. Returns the name of the domain or workgroup this machine belongs to.
  2662. Arguments:
  2663. DomainNamePtr - The name of the domain or workgroup
  2664. IsWorkgroupName - Returns TRUE if the name is a workgroup name.
  2665. Returns FALSE if the name is a domain name.
  2666. Return Value:
  2667. NERR_Success - Success.
  2668. NERR_CfgCompNotFound - There was an error determining the domain name
  2669. --*/
  2670. {
  2671. NTSTATUS status;
  2672. LSA_HANDLE PolicyHandle;
  2673. PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo;
  2674. OBJECT_ATTRIBUTES ObjAttributes;
  2675. UNICODE_STRING UniServerName;
  2676. //
  2677. // Check for caller's errors.
  2678. //
  2679. if ( DomainNamePtr == NULL ) {
  2680. return STATUS_INVALID_PARAMETER;
  2681. }
  2682. //
  2683. // Open a handle to the local security policy. Initialize the
  2684. // objects attributes structure first.
  2685. //
  2686. InitializeObjectAttributes(
  2687. &ObjAttributes,
  2688. NULL,
  2689. 0L,
  2690. NULL,
  2691. NULL
  2692. );
  2693. RtlInitUnicodeString( &UniServerName, ServerNamePtr );
  2694. status = LsaOpenPolicy(
  2695. &UniServerName,
  2696. &ObjAttributes,
  2697. POLICY_VIEW_LOCAL_INFORMATION,
  2698. &PolicyHandle
  2699. );
  2700. KdPrint( ( "TSUSEREX - GetDomainName: LsaOpenPolicy returned NTSTATUS = 0x%x\n", status ) );
  2701. if (! NT_SUCCESS(status)) {
  2702. return( status );
  2703. }
  2704. //
  2705. // Get the name of the primary domain from LSA
  2706. //
  2707. status = LsaQueryInformationPolicy(
  2708. PolicyHandle,
  2709. PolicyAccountDomainInformation,
  2710. (PVOID *)&DomainInfo
  2711. );
  2712. KdPrint( ( "TSUSEREX - GetDomainName: LsaQueryInformationPolicy returned NTSTATUS = 0x%x\n", status ) );
  2713. if (! NT_SUCCESS(status)) {
  2714. (void) LsaClose(PolicyHandle);
  2715. return( status );
  2716. }
  2717. (void) LsaClose(PolicyHandle);
  2718. lstrcpy( DomainNamePtr , DomainInfo->DomainName.Buffer );
  2719. (void) LsaFreeMemory((PVOID) DomainInfo);
  2720. return( STATUS_SUCCESS );
  2721. }
  2722. #endif
  2723. BOOL CProfileDlg::createdir( LPTSTR szPath , BOOL bIsRemote , PDWORD pdwErr )
  2724. {
  2725. int npos = 0;
  2726. *pdwErr = ERROR_INVALID_NAME;
  2727. if( bIsRemote )
  2728. {
  2729. // skip over three four whacks
  2730. npos = 2;
  2731. if( szPath[0] != TEXT( '\\' ) && szPath[1] != TEXT( '\\' ) )
  2732. {
  2733. return FALSE;
  2734. }
  2735. for( int n = 0; n < 2 ; n++ )
  2736. {
  2737. while( szPath[ npos ] != TEXT( '\\' ) && szPath[ npos ] != TEXT( '\0' ) )
  2738. {
  2739. npos++;
  2740. }
  2741. if( szPath[ npos ] == TEXT( '\0' ) )
  2742. {
  2743. return FALSE;
  2744. }
  2745. npos++;
  2746. }
  2747. }
  2748. else
  2749. {
  2750. if( szPath[1] != TEXT( ':' ) && szPath[2] != TEXT( '\\' ) )
  2751. {
  2752. return FALSE;
  2753. }
  2754. npos = 3;
  2755. }
  2756. SECURITY_ATTRIBUTES securityAttributes;
  2757. ZeroMemory( &securityAttributes , sizeof( SECURITY_ATTRIBUTES ) );
  2758. // its redundant to check the bIsRemote flag since for dsadmin createdir is only called for
  2759. // UNC paths
  2760. if( m_pUSht->GetDSAType() && bIsRemote )
  2761. {
  2762. //
  2763. // From EricB's DSPROP_CreateHomeDirectory
  2764. PSID psidAdmins = NULL;
  2765. SID_IDENTIFIER_AUTHORITY NtAuth = SECURITY_NT_AUTHORITY;
  2766. if (!AllocateAndInitializeSid(&NtAuth,
  2767. 2,
  2768. SECURITY_BUILTIN_DOMAIN_RID,
  2769. DOMAIN_ALIAS_RID_ADMINS,
  2770. 0, 0, 0, 0, 0, 0,
  2771. &psidAdmins ) )
  2772. {
  2773. ODS( L"AllocateAndInitializeSid failed\n");
  2774. *pdwErr = GetLastError( );
  2775. return FALSE;
  2776. }
  2777. // build a DACL
  2778. PACL pDacl;
  2779. static const int nAceCount = 2;
  2780. PSID pAceSid[nAceCount];
  2781. pAceSid[0] = m_pUSht->GetUserSid( );
  2782. pAceSid[1] = psidAdmins;
  2783. EXPLICIT_ACCESS rgAccessEntry[nAceCount] = {0};
  2784. for (int i = 0 ; i < nAceCount; i++)
  2785. {
  2786. rgAccessEntry[i].grfAccessPermissions = GENERIC_ALL;
  2787. rgAccessEntry[i].grfAccessMode = GRANT_ACCESS;
  2788. rgAccessEntry[i].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  2789. // build the trustee structs
  2790. //
  2791. BuildTrusteeWithSid(&(rgAccessEntry[i].Trustee),
  2792. pAceSid[i]);
  2793. }
  2794. // add the entries to the ACL
  2795. //
  2796. *pdwErr = SetEntriesInAcl( nAceCount, rgAccessEntry, NULL, &pDacl );
  2797. if( *pdwErr != 0 )
  2798. {
  2799. ODS( L"SetEntriesInAcl() failed\n" );
  2800. return FALSE;
  2801. }
  2802. // build a security descriptor and initialize it
  2803. // in absolute format
  2804. SECURITY_DESCRIPTOR securityDescriptor;
  2805. PSECURITY_DESCRIPTOR pSecurityDescriptor = &securityDescriptor;
  2806. if( !InitializeSecurityDescriptor( pSecurityDescriptor , SECURITY_DESCRIPTOR_REVISION ) )
  2807. {
  2808. ODS( L"InitializeSecurityDescriptor() failed\n" );
  2809. *pdwErr = GetLastError( );
  2810. return FALSE;
  2811. }
  2812. // add DACL to security descriptor (must be in absolute format)
  2813. if( !SetSecurityDescriptorDacl( pSecurityDescriptor,
  2814. TRUE, // bDaclPresent
  2815. pDacl,
  2816. FALSE // bDaclDefaulted
  2817. ) )
  2818. {
  2819. ODS( L"SetSecurityDescriptorDacl() failed\n" );
  2820. *pdwErr = GetLastError( );
  2821. return FALSE;
  2822. }
  2823. // set the owner of the directory
  2824. if( !SetSecurityDescriptorOwner( pSecurityDescriptor ,
  2825. m_pUSht->GetUserSid( ) ,
  2826. FALSE // bOwnerDefaulted
  2827. ) )
  2828. {
  2829. ODS( L"SetSecurityDescriptorOwner() failed\n" );
  2830. *pdwErr = GetLastError( );
  2831. return FALSE;
  2832. }
  2833. ASSERT_( IsValidSecurityDescriptor( pSecurityDescriptor ) );
  2834. // build a SECURITY_ATTRIBUTES struct as argument for
  2835. // CreateDirectory()
  2836. securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  2837. securityAttributes.lpSecurityDescriptor = pSecurityDescriptor;
  2838. securityAttributes.bInheritHandle = FALSE;
  2839. if( !CreateDirectory( szPath , &securityAttributes ) )
  2840. {
  2841. *pdwErr = GetLastError( );
  2842. if( psidAdmins != NULL )
  2843. {
  2844. FreeSid( psidAdmins );
  2845. }
  2846. return FALSE;
  2847. }
  2848. FreeSid( psidAdmins );
  2849. }
  2850. else
  2851. {
  2852. while( szPath[ npos ] != TEXT( '\0' ) )
  2853. {
  2854. while( szPath[ npos ] != TEXT( '\\' ) && szPath[ npos ] != TEXT( '\0' ) )
  2855. {
  2856. npos++;
  2857. }
  2858. if( szPath[ npos ] == TEXT( '\0' ) )
  2859. {
  2860. if (!CreateSecureDir(szPath , pdwErr))
  2861. {
  2862. ODS(L"CreateSecureDir failed\n");
  2863. return FALSE;
  2864. }
  2865. }
  2866. else
  2867. {
  2868. szPath[ npos ] = 0;
  2869. if (!CreateSecureDir(szPath , pdwErr))
  2870. {
  2871. ODS(L"CreateSecureDir failed\n");
  2872. return FALSE;
  2873. }
  2874. szPath[ npos ] = TEXT( '\\' );
  2875. npos++;
  2876. }
  2877. }
  2878. }
  2879. *pdwErr = 0;
  2880. return TRUE;
  2881. }
  2882. DWORD
  2883. GetUserSid(LPCTSTR pwszAccountName,
  2884. LPCTSTR pwszServerName,
  2885. PSID* ppUserSid)
  2886. {
  2887. DWORD cbSid = 0;
  2888. DWORD cbDomain = 0;
  2889. PSID pSID = NULL;
  2890. LPTSTR pszDomain = NULL;
  2891. BOOL bStatus;
  2892. DWORD dwStatus = ERROR_SUCCESS;
  2893. SID_NAME_USE seUse;
  2894. bStatus = LookupAccountName(pwszServerName,
  2895. pwszAccountName,
  2896. NULL,
  2897. &cbSid,
  2898. NULL,
  2899. &cbDomain,
  2900. &seUse);
  2901. if(!bStatus)
  2902. {
  2903. dwStatus = GetLastError();
  2904. if(dwStatus != ERROR_INSUFFICIENT_BUFFER)
  2905. {
  2906. goto Cleanup;
  2907. }
  2908. }
  2909. dwStatus = ERROR_SUCCESS;
  2910. pSID = (PSID)LocalAlloc(LMEM_FIXED, cbSid );
  2911. pszDomain = (LPTSTR)LocalAlloc(LMEM_FIXED, sizeof(TCHAR) * (cbDomain + 1));
  2912. if(pSID == NULL || pszDomain == NULL)
  2913. {
  2914. dwStatus = GetLastError();
  2915. goto Cleanup;
  2916. }
  2917. bStatus = LookupAccountName(pwszServerName,
  2918. pwszAccountName,
  2919. pSID,
  2920. &cbSid,
  2921. pszDomain,
  2922. &cbDomain,
  2923. &seUse);
  2924. if(!bStatus)
  2925. {
  2926. dwStatus = GetLastError();
  2927. goto Cleanup;
  2928. }
  2929. *ppUserSid = pSID;
  2930. pSID = NULL;
  2931. Cleanup:
  2932. if(pszDomain != NULL)
  2933. {
  2934. LocalFree(pszDomain);
  2935. }
  2936. if(pSID != NULL)
  2937. {
  2938. LocalFree(pSID);
  2939. }
  2940. return dwStatus;
  2941. }
  2942. BOOL
  2943. CProfileDlg::CreateSecureDir(LPTSTR szPath , PDWORD pdwErr)
  2944. {
  2945. BOOL bRetVal = TRUE;
  2946. static const int nAceCount = 2;
  2947. PACL pDacl = NULL;
  2948. PSID psidAdmins = NULL;
  2949. PSID psidUser = NULL;
  2950. PSECURITY_DESCRIPTOR pSD = NULL;
  2951. SID_IDENTIFIER_AUTHORITY NtAuth = SECURITY_NT_AUTHORITY;
  2952. EXPLICIT_ACCESS rgAccessEntry[nAceCount] = {0};
  2953. SECURITY_ATTRIBUTES securityAttributes;
  2954. DWORD dwStatus;
  2955. LPWSTR pszServer = NULL;
  2956. _ASSERT(szPath);
  2957. // Make sure a valid string is passed in
  2958. if (szPath == NULL)
  2959. {
  2960. ODS( L"Path not valid.\n");
  2961. return FALSE;
  2962. }
  2963. // Create a SID for the BUILTIN Administrators group.
  2964. if (!AllocateAndInitializeSid(&NtAuth,
  2965. 2,
  2966. SECURITY_BUILTIN_DOMAIN_RID,
  2967. DOMAIN_ALIAS_RID_ADMINS,
  2968. 0, 0, 0, 0, 0, 0,
  2969. &psidAdmins))
  2970. {
  2971. ODS( L"AllocateAndInitializeSid failed\n");
  2972. goto Error;
  2973. }
  2974. // Initialize an EXPLICIT_ACCESS structure for an ACE.
  2975. // The ACE will allow the Administrators group full access to the key.
  2976. rgAccessEntry[0].grfAccessPermissions = GENERIC_ALL;
  2977. rgAccessEntry[0].grfAccessMode = GRANT_ACCESS;
  2978. rgAccessEntry[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  2979. // build the trustee structs
  2980. BuildTrusteeWithSid(&(rgAccessEntry[0].Trustee), psidAdmins);
  2981. // Get the SID for the user
  2982. m_pUSht->GetServer(&pszServer);
  2983. if (pszServer == NULL)
  2984. {
  2985. ODS(L"GetServer() failed\n");
  2986. bRetVal = FALSE;
  2987. goto Cleanup;
  2988. }
  2989. dwStatus = GetUserSid(m_pUSht->GetUserName(), pszServer, &psidUser);
  2990. if (dwStatus != ERROR_SUCCESS)
  2991. {
  2992. ODS(L"GetUserSid() failed\n");
  2993. bRetVal = FALSE;
  2994. goto Cleanup;
  2995. }
  2996. // Specify the access control for the selected User, (full access)
  2997. rgAccessEntry[1].grfAccessPermissions = GENERIC_ALL;
  2998. rgAccessEntry[1].grfAccessMode = GRANT_ACCESS;
  2999. rgAccessEntry[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  3000. rgAccessEntry[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  3001. rgAccessEntry[1].Trustee.TrusteeType = TRUSTEE_IS_USER;
  3002. rgAccessEntry[1].Trustee.ptstrName = (LPWSTR)psidUser;
  3003. // Create a new ACL that contains the new ACEs.
  3004. *pdwErr = SetEntriesInAcl(nAceCount, rgAccessEntry, NULL, &pDacl);
  3005. if(*pdwErr != 0)
  3006. {
  3007. ODS(L"SetEntriesInAcl() failed\n");
  3008. bRetVal = FALSE;
  3009. goto Cleanup;
  3010. }
  3011. // Initialize a security descriptor.
  3012. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
  3013. SECURITY_DESCRIPTOR_MIN_LENGTH);
  3014. if (pSD == NULL)
  3015. {
  3016. ODS( L"LocalAlloc Error\n" );
  3017. goto Error;
  3018. }
  3019. if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
  3020. ODS( L"InitializeSecurityDescriptor() failed\n" );
  3021. goto Error;
  3022. }
  3023. // Add the ACL to the security descriptor
  3024. if(!SetSecurityDescriptorDacl(pSD,
  3025. TRUE, // bDaclPresent
  3026. pDacl,
  3027. FALSE)) // bDaclDefaulted
  3028. {
  3029. ODS( L"SetSecurityDescriptorDacl() failed\n" );
  3030. goto Error;
  3031. }
  3032. // Initialize a security attributes structure.
  3033. ZeroMemory(&securityAttributes , sizeof(SECURITY_ATTRIBUTES));
  3034. securityAttributes.nLength = sizeof(pSD);
  3035. securityAttributes.lpSecurityDescriptor = pSD;
  3036. securityAttributes.bInheritHandle = FALSE;
  3037. if(!CreateDirectory(szPath, &securityAttributes))
  3038. {
  3039. *pdwErr = GetLastError();
  3040. // If the directory already exists it's ok
  3041. if (*pdwErr != ERROR_ALREADY_EXISTS)
  3042. {
  3043. ODS(L"CreateDirectory failed\n");
  3044. ODS(szPath);
  3045. goto Error;
  3046. }
  3047. }
  3048. *pdwErr = 0;
  3049. Cleanup:
  3050. if (pDacl != NULL)
  3051. LocalFree(pDacl);
  3052. if (pSD != NULL)
  3053. LocalFree(pSD);
  3054. if (psidAdmins != NULL)
  3055. FreeSid(psidAdmins);
  3056. if (pszServer != NULL)
  3057. delete[] pszServer;
  3058. if (psidUser != NULL)
  3059. LocalFree(psidUser);
  3060. return bRetVal;
  3061. Error:
  3062. *pdwErr = GetLastError();
  3063. bRetVal = FALSE;
  3064. goto Cleanup;
  3065. }