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.

3077 lines
83 KiB

  1. //
  2. // Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  3. //
  4. //
  5. //
  6. //==============================================================;
  7. #include "RemotePage.h"
  8. #include <lm.h>
  9. #include <crtdbg.h>
  10. #include <shellapi.h>
  11. #include <htmlhelp.h>
  12. #include "resource.h"
  13. #include <shgina.h>
  14. #include "RAssistance.h"
  15. #include "RAssistance_i.c"
  16. #include <winsta.h>
  17. #include "cfgbkend.h"
  18. #include "cfgbkend_i.c"
  19. extern ULONG g_uObjects;
  20. IRASettingProperty* g_praSetting = NULL; // Used for Remote assistance setting
  21. #define NO_HELP ((DWORD) -1) // Disables Help for a control
  22. //Table of help IDs for each control
  23. DWORD aHelpIds[] = {
  24. IDC_REMOTE_ENABLE, HIDC_REMOTE_ENABLE,
  25. IDC_REMOTE_USR_LIST, HIDC_REMOTE_USR_LIST,
  26. IDC_REMOTE_USR_ADD, HIDC_REMOTE_USR_ADD,
  27. IDC_REMOTE_USR_REMOVE, HIDC_REMOTE_USR_REMOVE,
  28. IDC_REMOTE_ASSISTANCE_ADVANCED, HIDC_RA_ADVANCED,
  29. IDC_ENABLERA, HIDC_RA_ENABLE,
  30. IDC_REMOTE_UPLINK, NO_HELP,
  31. IDC_REMOTE_GPLINK_APPSERVER, NO_HELP,
  32. IDC_REMOTE_SCLINK_APPSERVER, NO_HELP,
  33. IDC_OFFLINE_FILES, NO_HELP,
  34. IDC_REMOTE_COMPNAME, NO_HELP,
  35. IDC_REMOTE_HELP, NO_HELP,
  36. IDC_REMOTE_HELP_APPSERVER, NO_HELP,
  37. IDC_REMOTE_SELECT_USERS, NO_HELP,
  38. IDC_DEFAULT1, NO_HELP,
  39. IDC_DEFAULT2, NO_HELP,
  40. IDC_DEFAULT3, NO_HELP,
  41. IDC_DEFAULT4, NO_HELP,
  42. IDC_DEFAULT5, NO_HELP,
  43. 0, 0
  44. };
  45. //*************************************************************
  46. //
  47. // CRemotePage::CRemotePage()
  48. //
  49. // Purpose: Initializes data members of the object
  50. //
  51. // Parameters: HINSTANCE hinst
  52. //
  53. // Return: NONE
  54. //
  55. // Comments:
  56. //
  57. // History: Date Author Comment
  58. // 3/13/00 a-skuzin Created
  59. //
  60. //*************************************************************
  61. CRemotePage::CRemotePage(
  62. IN HINSTANCE hinst) :
  63. m_RemoteUsersDialog(hinst)
  64. {
  65. m_cref = 1; //
  66. m_bProfessional = FALSE;
  67. m_dwPageType = PAGE_TYPE_UNKNOWN;
  68. m_hInst = hinst;
  69. m_bDisableChkBox = FALSE;
  70. m_bDisableButtons = FALSE;
  71. m_bShowAccessDeniedWarning = FALSE;
  72. m_dwInitialState = 0;
  73. m_hDlg = NULL;
  74. m_TemplateId = 0;
  75. g_uObjects++;
  76. }
  77. //*************************************************************
  78. //
  79. // CRemotePage::~CRemotePage()
  80. //
  81. // Purpose: decreases the object counter
  82. //
  83. // Parameters: NONE
  84. //
  85. // Return: NONE
  86. //
  87. // Comments:
  88. //
  89. // History: Date Author Comment
  90. // 3/13/00 a-skuzin Created
  91. //
  92. //*************************************************************
  93. CRemotePage::~CRemotePage()
  94. {
  95. g_uObjects--;
  96. }
  97. ///////////////////////////////
  98. // Interface IUnknown
  99. ///////////////////////////////
  100. STDMETHODIMP
  101. CRemotePage::QueryInterface(
  102. IN REFIID riid,
  103. OUT LPVOID *ppv)
  104. {
  105. if (!ppv)
  106. return E_FAIL;
  107. *ppv = NULL;
  108. if (IsEqualIID(riid, IID_IUnknown))
  109. *ppv = static_cast<IShellPropSheetExt *>(this);
  110. else if (IsEqualIID(riid, IID_IShellExtInit))
  111. *ppv = static_cast<IShellExtInit *>(this);
  112. else if (IsEqualIID(riid, IID_IShellPropSheetExt))
  113. *ppv = static_cast<IShellPropSheetExt *>(this);
  114. if (*ppv)
  115. {
  116. AddRef();
  117. return S_OK;
  118. }
  119. return E_NOINTERFACE;
  120. }
  121. STDMETHODIMP_(ULONG)
  122. CRemotePage::AddRef()
  123. {
  124. return ++m_cref;
  125. }
  126. STDMETHODIMP_(ULONG)
  127. CRemotePage::Release()
  128. {
  129. m_cref--;
  130. if (!m_cref)
  131. {
  132. delete this;
  133. return 0;
  134. }
  135. return m_cref;
  136. }
  137. ///////////////////////////////
  138. // Interface IShellExtInit
  139. ///////////////////////////////
  140. STDMETHODIMP
  141. CRemotePage::Initialize(
  142. IN LPCITEMIDLIST pidlFolder,
  143. IN LPDATAOBJECT lpdobj,
  144. IN HKEY hkeyProgID )
  145. {
  146. return S_OK;
  147. }
  148. ///////////////////////////////
  149. // Interface IShellPropSheetExt
  150. ///////////////////////////////
  151. //*************************************************************
  152. //
  153. // AddPages()
  154. //
  155. // Purpose: Adds "Remote" tab to a property sheet
  156. //
  157. // Parameters: lpfnAddPage - function to call to add a page
  158. // lParam - Parameter to pass to the function specified by the lpfnAddPage
  159. //
  160. // Return: TRUE if message was processed
  161. // FALSE if not
  162. //
  163. // Comments:
  164. //
  165. // History: Date Author Comment
  166. // 3/13/00 a-skuzin Created
  167. //
  168. //*************************************************************
  169. STDMETHODIMP
  170. CRemotePage::AddPages(
  171. IN LPFNADDPROPSHEETPAGE lpfnAddPage,
  172. IN LPARAM lParam )
  173. {
  174. if(CanShowRemotePage())
  175. {
  176. PROPSHEETPAGE psp;
  177. psp.dwSize = sizeof(PROPSHEETPAGE);
  178. psp.dwFlags = 0;
  179. psp.hInstance = m_hInst;
  180. psp.pszTemplate = MAKEINTRESOURCE(m_TemplateId);
  181. psp.pfnDlgProc = RemoteDlgProc;
  182. psp.pszTitle = NULL;
  183. psp.lParam = (LPARAM)this;
  184. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&psp);
  185. if(hPage && lpfnAddPage(hPage,lParam))
  186. {
  187. return S_OK;
  188. }
  189. }
  190. return E_FAIL;
  191. }
  192. STDMETHODIMP
  193. CRemotePage::ReplacePage(
  194. IN UINT uPageID,
  195. IN LPFNADDPROPSHEETPAGE lpfnReplacePage,
  196. IN LPARAM lParam )
  197. {
  198. return E_FAIL;
  199. }
  200. //*************************************************************
  201. //
  202. // RemoteDlgProc()
  203. //
  204. // Purpose: Dialog box procedure for Remote tab
  205. //
  206. // Parameters: hDlg - handle to the dialog box
  207. // uMsg - window message
  208. // wParam - wParam
  209. // lParam - lParam
  210. //
  211. // Return: TRUE if message was processed
  212. // FALSE if not
  213. //
  214. // Comments:
  215. //
  216. // History: Date Author Comment
  217. // 3/13/00 a-skuzin Created
  218. //
  219. //*************************************************************
  220. INT_PTR APIENTRY
  221. RemoteDlgProc (
  222. HWND hDlg,
  223. UINT uMsg,
  224. WPARAM wParam,
  225. LPARAM lParam)
  226. {
  227. CRemotePage *pPage = (CRemotePage *) GetWindowLongPtr(hDlg, DWLP_USER);
  228. switch (uMsg)
  229. {
  230. case WM_INITDIALOG:
  231. {
  232. PROPSHEETPAGE *ppsp=(PROPSHEETPAGE *)lParam;
  233. pPage = (CRemotePage *)ppsp->lParam;
  234. SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)pPage);
  235. if(pPage)
  236. {
  237. pPage->AddRef();
  238. pPage->OnInitDialog(hDlg);
  239. }
  240. }
  241. break;
  242. case WM_NOTIFY:
  243. switch (((NMHDR FAR*)lParam)->code)
  244. {
  245. case NM_CLICK:
  246. case NM_RETURN:
  247. // Is for RA's help?
  248. if (wParam == IDC_REMOTERA_HELP)
  249. {
  250. #if 0
  251. #define HELP_PATH TEXT("\\PCHEALTH\\HelpCtr\\Binaries\\HelpCtr.exe -FromStartHelp -Mode \"hcp://CN=Microsoft Corporation,L=Redmond,S=Washington,C=US/Remote Assistance/RAIMLayout.xml\" -Url \"hcp://CN=Microsoft Corporation,L=Redmond,S=Washington,C=US/Remote%20Assistance/Common/RCMoreInfo.htm\"")
  252. TCHAR szCommandLine[2000];
  253. PROCESS_INFORMATION ProcessInfo;
  254. STARTUPINFO StartUpInfo;
  255. TCHAR szWinDir[2048];
  256. GetWindowsDirectory(szWinDir, 2048);
  257. ZeroMemory((LPVOID)&StartUpInfo, sizeof(STARTUPINFO));
  258. StartUpInfo.cb = sizeof(STARTUPINFO);
  259. wsprintf(szCommandLine, TEXT("%s%s"), szWinDir,HELP_PATH);
  260. CreateProcess(NULL, szCommandLine,NULL,NULL,TRUE,CREATE_NEW_PROCESS_GROUP,NULL,&szWinDir[0],&StartUpInfo,&ProcessInfo);
  261. #else
  262. HtmlHelp(NULL, TEXT("remasst.chm"), HH_HELP_FINDER, 0);
  263. #endif
  264. }
  265. else if(pPage)
  266. {
  267. pPage->OnLink(wParam);
  268. }
  269. break;
  270. case PSN_APPLY:
  271. if(pPage)
  272. {
  273. if(pPage->OnApply())
  274. {
  275. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,PSNRET_NOERROR);
  276. }
  277. else
  278. {
  279. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,PSNRET_INVALID);
  280. }
  281. }
  282. return TRUE;
  283. case PSN_SETACTIVE:
  284. if(pPage)
  285. {
  286. pPage->OnSetActive();
  287. }
  288. return TRUE;
  289. default:
  290. return FALSE;
  291. }
  292. break;
  293. case WM_COMMAND:
  294. {
  295. switch(LOWORD(wParam))
  296. {
  297. case IDC_REMOTE_ENABLE:
  298. if(pPage && pPage->OnRemoteEnable())
  299. {
  300. pPage->RemoteEnableWarning();
  301. PropSheet_Changed(GetParent(hDlg), hDlg);
  302. }
  303. break;
  304. case IDC_REMOTE_SELECT_USERS:
  305. if(pPage)
  306. {
  307. pPage->OnRemoteSelectUsers();
  308. }
  309. break;
  310. // Remote Assistance Dialog button.
  311. case IDC_REMOTE_ASSISTANCE_ADVANCED:
  312. {
  313. BOOL bIsChanged = FALSE;
  314. if (!g_praSetting)
  315. {
  316. CoCreateInstance(CLSID_RASettingProperty,
  317. NULL,
  318. CLSCTX_INPROC_SERVER,
  319. IID_IRASettingProperty,
  320. reinterpret_cast<void**>(&g_praSetting));
  321. // Need to init it at the first time.
  322. if (g_praSetting)
  323. {
  324. g_praSetting->Init();
  325. }
  326. else
  327. {
  328. // Not enough memory, too bad.
  329. return TRUE;
  330. }
  331. }
  332. g_praSetting->ShowDialogBox(hDlg);
  333. if (SUCCEEDED(g_praSetting->get_IsChanged(&bIsChanged)) && bIsChanged)
  334. {
  335. PropSheet_Changed(GetParent(hDlg), hDlg);
  336. }
  337. }
  338. break;
  339. case IDC_ENABLERA:
  340. {
  341. PropSheet_Changed(GetParent(hDlg), hDlg);
  342. EnableWindow(GetDlgItem(hDlg,IDC_REMOTE_ASSISTANCE_ADVANCED),
  343. IsDlgButtonChecked(hDlg, IDC_ENABLERA));
  344. }
  345. break;
  346. default:
  347. break;
  348. }
  349. }
  350. return FALSE;
  351. case WM_DESTROY:
  352. if(pPage)
  353. {
  354. pPage->Release();
  355. }
  356. if (g_praSetting)
  357. {
  358. g_praSetting->Release();
  359. g_praSetting = NULL;
  360. }
  361. return FALSE; //If an application processes this message, it should return zero.
  362. case WM_HELP:
  363. {
  364. LPHELPINFO phi=(LPHELPINFO)lParam;
  365. if(phi && phi->dwContextId)
  366. {
  367. WinHelp(hDlg,TEXT("SYSDM.HLP"),HELP_CONTEXTPOPUP,phi->dwContextId);
  368. }
  369. }
  370. break;
  371. case WM_CONTEXTMENU: // right mouse click
  372. WinHelp((HWND) wParam, TEXT("SYSDM.HLP"), HELP_CONTEXTMENU,
  373. (DWORD_PTR)aHelpIds);
  374. break;
  375. default:
  376. return FALSE;
  377. }
  378. return TRUE;
  379. }
  380. //*************************************************************
  381. //
  382. // CRemotePage::CanShowRemotePage()
  383. //
  384. // Purpose: Checks Windows version;
  385. // searches for "FDenyTSConnections" value first
  386. // in HKLM\\Software\\Policies\\Microsoft\\Windows NT\\Terminal Services
  387. // if not found than in
  388. // SYSTEM\\CurrentControlSet\\Control\\Terminal Server;
  389. // creates "Remote Desktop Users" SID,
  390. // gets "Remote Desktop Users" group name from the SID
  391. //
  392. // Parameters: hInst - hInstance
  393. // dwPageType - can be PAGE_TYPE_PTS or PAGE_TYPE_APPSERVER
  394. //
  395. // Return: TRUE if can show remote page
  396. //
  397. // Comments:
  398. //
  399. // History: Date Author Comment
  400. // 3/13/00 a-skuzin Created
  401. //
  402. //*************************************************************
  403. BOOL
  404. CRemotePage::CanShowRemotePage()
  405. {
  406. BOOL fCreatePage = FALSE;
  407. //Check Windows version
  408. OSVERSIONINFOEX ov;
  409. ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  410. if(!GetVersionEx((LPOSVERSIONINFO)&ov))
  411. {
  412. return FALSE;
  413. }
  414. if(ov.wProductType == VER_NT_WORKSTATION &&
  415. (ov.wSuiteMask & VER_SUITE_SINGLEUSERTS ))
  416. {
  417. fCreatePage = TRUE;
  418. if(ov.wSuiteMask & VER_SUITE_PERSONAL)
  419. {
  420. #ifdef _WIN64
  421. // No Remote Assistance on WIN64
  422. fCreatePage = FALSE;
  423. #else
  424. m_dwPageType = PAGE_TYPE_PERSONAL;
  425. m_TemplateId = IDD_REMOTE_PERSONAL;
  426. #endif
  427. }
  428. else
  429. {
  430. m_bProfessional = TRUE;
  431. m_dwPageType = PAGE_TYPE_PTS;
  432. m_TemplateId = IDD_REMOTE_PTS;
  433. }
  434. }
  435. else
  436. {
  437. if((ov.wProductType == VER_NT_DOMAIN_CONTROLLER || ov.wProductType == VER_NT_SERVER) &&
  438. (ov.wSuiteMask & VER_SUITE_TERMINAL) &&
  439. TestUserForAdmin())
  440. {
  441. fCreatePage = TRUE;
  442. if(ov.wSuiteMask & VER_SUITE_SINGLEUSERTS)
  443. {
  444. m_dwPageType = PAGE_TYPE_PTS;
  445. m_TemplateId = IDD_REMOTE_PTS;
  446. }
  447. else
  448. {
  449. m_dwPageType = PAGE_TYPE_APPSERVER;
  450. m_TemplateId = IDD_REMOTE_APPSERVER;
  451. }
  452. }
  453. }
  454. if( !fCreatePage)
  455. {
  456. return FALSE;
  457. }
  458. DWORD dwType;
  459. DWORD cbDisable;
  460. LONG Err;
  461. HKEY hKey;
  462. Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  463. TEXT("Software\\Policies\\Microsoft\\Windows NT\\Terminal Services"),
  464. 0,
  465. KEY_QUERY_VALUE,
  466. &hKey);
  467. if(Err == ERROR_SUCCESS)
  468. {
  469. cbDisable = sizeof(DWORD);
  470. Err = RegQueryValueEx(hKey,
  471. TEXT("fDenyTSConnections"),
  472. NULL,
  473. &dwType,
  474. (LPBYTE)&m_dwInitialState,
  475. &cbDisable);
  476. if(Err == ERROR_SUCCESS)
  477. {
  478. m_bDisableChkBox = TRUE;
  479. if(m_dwInitialState != 0)
  480. {
  481. m_bDisableButtons = TRUE;
  482. }
  483. }
  484. RegCloseKey(hKey);
  485. }
  486. if(Err != ERROR_SUCCESS)
  487. {
  488. if(Err != ERROR_FILE_NOT_FOUND)
  489. {
  490. return FALSE;
  491. }
  492. Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  493. TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"),
  494. 0,
  495. KEY_QUERY_VALUE,
  496. &hKey);
  497. if(Err == ERROR_SUCCESS)
  498. {
  499. cbDisable = sizeof(DWORD);
  500. Err = RegQueryValueEx(hKey,
  501. TEXT("fDenyTSConnections"),
  502. NULL,
  503. &dwType,
  504. (LPBYTE)&m_dwInitialState,
  505. &cbDisable);
  506. RegCloseKey(hKey);
  507. }
  508. if(Err != ERROR_SUCCESS && Err != ERROR_FILE_NOT_FOUND )
  509. {
  510. return FALSE;
  511. }
  512. }
  513. //Check permissions
  514. //on the registry
  515. if( !m_bDisableChkBox )
  516. {
  517. Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  518. TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"),
  519. 0,
  520. KEY_SET_VALUE,
  521. &hKey);
  522. if( Err == ERROR_SUCCESS )
  523. {
  524. RegCloseKey(hKey);
  525. }
  526. else
  527. {
  528. if( Err == ERROR_ACCESS_DENIED )
  529. {
  530. m_bDisableChkBox = TRUE;
  531. m_bShowAccessDeniedWarning = TRUE;
  532. }
  533. }
  534. }
  535. if(m_dwPageType == PAGE_TYPE_PTS)
  536. {
  537. if(!m_bDisableButtons)
  538. {
  539. if(!m_RemoteUsersDialog.CanShowDialog(&m_bShowAccessDeniedWarning))
  540. {
  541. m_bDisableButtons = TRUE;
  542. }
  543. if(m_bShowAccessDeniedWarning)
  544. {
  545. m_bDisableButtons = TRUE;
  546. }
  547. }
  548. }
  549. return TRUE;
  550. }
  551. //*************************************************************
  552. //
  553. // CRemotePage::OnInitDialog()
  554. //
  555. // Purpose: initializes check box state
  556. // creates list of "Remote Desktop Users" members
  557. //
  558. // Parameters: hDlg - the page handle
  559. //
  560. // Return: NONE
  561. //
  562. // Comments:
  563. //
  564. // History: Date Author Comment
  565. // 3/13/00 a-skuzin Created
  566. //
  567. //*************************************************************
  568. void
  569. CRemotePage::OnInitDialog(
  570. IN HWND hDlg)
  571. {
  572. m_hDlg = hDlg;
  573. /* Get Remote Assistance button value */
  574. BOOL bRAEnable = FALSE;
  575. int iErr;
  576. HKEY hKey = NULL;
  577. IRARegSetting* pRA = NULL;
  578. CoCreateInstance(CLSID_RARegSetting,
  579. NULL,
  580. CLSCTX_INPROC_SERVER,
  581. IID_IRARegSetting,
  582. reinterpret_cast<void**>(&pRA));
  583. if (pRA)
  584. {
  585. pRA->get_AllowGetHelpCPL(&bRAEnable);
  586. pRA->Release();
  587. }
  588. CheckDlgButton(m_hDlg, IDC_ENABLERA, bRAEnable?BST_CHECKED:BST_UNCHECKED);
  589. // check if users have permission to change this setting.
  590. iErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  591. TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"),
  592. 0,
  593. KEY_SET_VALUE,
  594. &hKey);
  595. if (iErr == ERROR_SUCCESS)
  596. {
  597. RegCloseKey(hKey);
  598. }
  599. else if (iErr == ERROR_ACCESS_DENIED)
  600. {
  601. bRAEnable = FALSE;
  602. EnableWindow(GetDlgItem(m_hDlg,IDC_ENABLERA), FALSE);
  603. }
  604. EnableWindow(GetDlgItem(m_hDlg,IDC_REMOTE_ASSISTANCE_ADVANCED), bRAEnable);
  605. /***** RA done *******/
  606. if(m_bDisableChkBox)
  607. {
  608. EnableWindow(GetDlgItem(m_hDlg,IDC_REMOTE_ENABLE),FALSE);
  609. }
  610. CheckDlgButton(m_hDlg,IDC_REMOTE_ENABLE,m_dwInitialState?BST_UNCHECKED:BST_CHECKED);
  611. if(m_dwPageType == PAGE_TYPE_PTS)
  612. {
  613. if(m_bDisableButtons)
  614. {
  615. EnableWindow(GetDlgItem(m_hDlg,IDC_REMOTE_SELECT_USERS),FALSE);
  616. }
  617. //Get computer name
  618. LPTSTR szCompName = (LPTSTR)LocalAlloc (LPTR, (MAX_PATH+1) * sizeof(TCHAR) );
  619. DWORD dwNameSize = MAX_PATH;
  620. if(szCompName)
  621. {
  622. BOOL bResult = GetComputerNameEx( ComputerNameDnsFullyQualified, szCompName, &dwNameSize );
  623. if(!bResult && GetLastError() == ERROR_MORE_DATA)
  624. {
  625. LocalFree(szCompName);
  626. szCompName = (LPTSTR) LocalAlloc (LPTR, (dwNameSize+1) * sizeof(TCHAR) );
  627. if ( szCompName )
  628. {
  629. bResult = GetComputerNameEx( ComputerNameDnsFullyQualified, szCompName, &dwNameSize );
  630. }
  631. }
  632. if(bResult)
  633. {
  634. SetDlgItemText(hDlg,IDC_REMOTE_COMPNAME,szCompName);
  635. }
  636. if(szCompName)
  637. {
  638. LocalFree(szCompName);
  639. }
  640. }
  641. }
  642. }
  643. //*************************************************************
  644. //
  645. // CRemotePage::OnSetActive()
  646. //
  647. // Purpose: When the page gets active and user does not have
  648. // permissions to change some settings it shows
  649. // a warning message.
  650. //
  651. // Parameters: NONE
  652. //
  653. // Return: NONE
  654. //
  655. // Comments:
  656. //
  657. // History: Date Author Comment
  658. // 3/13/00 a-skuzin Created
  659. //
  660. //*************************************************************
  661. void
  662. CRemotePage::OnSetActive()
  663. {
  664. TCHAR szMsg[MAX_PATH+1];
  665. TCHAR szTitle[MAX_PATH+1];
  666. if( m_bShowAccessDeniedWarning )
  667. {
  668. if(LoadString(m_hInst,IDS_REMOTE_SESSIONS,szTitle,MAX_PATH) &&
  669. LoadString(m_hInst,IDS_WRN_NO_PERMISSIONS,szMsg,MAX_PATH))
  670. {
  671. MessageBox(m_hDlg,szMsg,szTitle,MB_OK|MB_ICONINFORMATION);
  672. }
  673. m_bShowAccessDeniedWarning = FALSE;
  674. }
  675. }
  676. //*************************************************************
  677. //
  678. // CRemotePage::OnApply()
  679. //
  680. // Purpose: saves settings in the Registry
  681. // saves "Remote Desktop Users" membership changes
  682. //
  683. // Parameters: NONE
  684. //
  685. // Return: TRUE - if changes can be applied
  686. // FALSE - otherwise.
  687. //
  688. // Comments: in case of error shows message box
  689. //
  690. // History: Date Author Comment
  691. // 3/13/00 a-skuzin Created
  692. //
  693. //*************************************************************
  694. BOOL
  695. CRemotePage::OnApply()
  696. {
  697. CWaitCursor wait;
  698. CMutex mutex;
  699. DWORD dwType = REG_DWORD;
  700. DWORD dwDisable = 0;
  701. DWORD cbDisable = sizeof(DWORD);
  702. LONG Err;
  703. // Update RA setting first
  704. IRARegSetting* pRA = NULL;
  705. CoCreateInstance(CLSID_RARegSetting,
  706. NULL,
  707. CLSCTX_INPROC_SERVER,
  708. IID_IRARegSetting,
  709. reinterpret_cast<void**>(&pRA));
  710. if (pRA)
  711. {
  712. pRA->put_AllowGetHelp(IsDlgButtonChecked(m_hDlg, IDC_ENABLERA)==BST_CHECKED);
  713. pRA->Release();
  714. }
  715. BOOL bIsChanged = FALSE;
  716. if (g_praSetting && SUCCEEDED(g_praSetting->get_IsChanged(&bIsChanged)) && bIsChanged)
  717. {
  718. g_praSetting->SetRegSetting();
  719. }
  720. // RA done.
  721. if(!OnRemoteEnable())
  722. {
  723. return FALSE;
  724. }
  725. if(IsWindowEnabled(GetDlgItem(m_hDlg,IDC_REMOTE_ENABLE)))
  726. {
  727. if(IsDlgButtonChecked(m_hDlg,IDC_REMOTE_ENABLE) == BST_UNCHECKED)
  728. {
  729. dwDisable = 1;
  730. }
  731. if(dwDisable != m_dwInitialState)
  732. {
  733. HRESULT hr;
  734. hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  735. if (SUCCEEDED(hr))
  736. {
  737. ILocalMachine *pLocalMachine;
  738. hr = CoCreateInstance(CLSID_ShellLocalMachine,
  739. NULL,
  740. CLSCTX_INPROC_SERVER,
  741. IID_ILocalMachine,
  742. reinterpret_cast<void**>(&pLocalMachine));
  743. if (SUCCEEDED(hr) && (pLocalMachine != NULL))
  744. {
  745. hr = pLocalMachine->put_isRemoteConnectionsEnabled(dwDisable == 0);
  746. pLocalMachine->Release();
  747. }
  748. CoUninitialize();
  749. }
  750. Err = HRESULT_CODE(hr);
  751. if (ERROR_SUCCESS == Err)
  752. {
  753. m_dwInitialState = dwDisable;
  754. }
  755. else
  756. {
  757. if (ERROR_NOT_SUPPORTED == Err)
  758. {
  759. TCHAR szContent[256], szTitle[256];
  760. (int)LoadString(m_hInst, IDS_OTHER_USERS, szContent, sizeof(szContent) / sizeof(szContent[0]));
  761. (int)LoadString(m_hInst, IDS_REMOTE_SESSIONS, szTitle, sizeof(szTitle) / sizeof(szTitle[0]));
  762. MessageBox(m_hDlg, szContent, szTitle, MB_OK | MB_ICONSTOP);
  763. }
  764. else
  765. {
  766. DisplayError(m_hInst, m_hDlg, Err, IDS_ERR_SAVE_REGISTRY, IDS_REMOTE_SESSIONS);
  767. }
  768. CheckDlgButton(m_hDlg, IDC_REMOTE_ENABLE, m_dwInitialState ? BST_UNCHECKED : BST_CHECKED);
  769. }
  770. }
  771. }
  772. return TRUE;
  773. }
  774. //*************************************************************
  775. //
  776. // CRemotePage::OnLink()
  777. //
  778. // Purpose: runs application which link points to.
  779. //
  780. // Parameters: WPARAM wParam - link ID
  781. //
  782. // Return: NONE
  783. //
  784. // Comments:
  785. //
  786. // History: Date Author Comment
  787. // 5/8/00 a-skuzin Created
  788. //
  789. //*************************************************************
  790. void
  791. CRemotePage::OnLink(
  792. WPARAM wParam)
  793. {
  794. switch(wParam)
  795. {
  796. case IDC_REMOTE_GPLINK_APPSERVER:
  797. ShellExecute(NULL,TEXT("open"),TEXT("gpedit.msc"),NULL,NULL,SW_SHOW);
  798. break;
  799. case IDC_REMOTE_SCLINK_APPSERVER:
  800. ShellExecute(NULL,TEXT("open"),TEXT("tscc.msc"),NULL,NULL,SW_SHOW);
  801. break;
  802. case IDC_REMOTE_UPLINK:
  803. ShellExecute(NULL,TEXT("open"),TEXT("control"),TEXT("userpasswords"),NULL,SW_SHOW);
  804. break;
  805. /*
  806. case IDC_REMOTE_HELP:
  807. HtmlHelp(NULL, TEXT("rdesktop.chm"), HH_HELP_FINDER, 0);
  808. break;*/
  809. case IDC_REMOTE_HELP:
  810. if(m_bProfessional)
  811. {
  812. ShellExecute(NULL,TEXT("open"),
  813. TEXT("hcp://services/subsite?node=TopLevelBucket_2/Working_Remotely/")
  814. TEXT("Remote_Desktop&topic=MS-ITS:rdesktop.chm::/rdesktop_overview.htm"),NULL,NULL,SW_SHOW);
  815. }
  816. else
  817. {
  818. ShellExecute(NULL,TEXT("open"),
  819. TEXT("hcp://services/subsite?node=Administration_and_Scripting_Tools/Remote_Administration_Tools/")
  820. TEXT("Remote_Administration_Using_Terminal_Services&topic=MS-ITS:rdesktop.chm::/rdesktops_chm_topnode.htm"),NULL,NULL,SW_SHOW);
  821. }
  822. break;
  823. case IDC_REMOTE_HELP_APPSERVER:
  824. ShellExecute(NULL,TEXT("open"),
  825. TEXT("hcp://services/subsite?node=Software_Deployment/")
  826. TEXT("Terminal_Services&topic=MS-ITS:termsrv.chm::/ts_chm_top.htm"),NULL,NULL,SW_SHOW);
  827. break;
  828. default:
  829. break;
  830. }
  831. }
  832. //*************************************************************
  833. //
  834. // CRemotePage::OnRemoteEnable()
  835. //
  836. // Purpose: If user tries to allow remote connections and
  837. // "Offline Files" is enabled it shows
  838. // "Disable Offline Files" dialog and unchecks
  839. // "Remote Connections" checkbox.
  840. //
  841. // Parameters: NONE
  842. //
  843. // Return: TRUE - if the check box state was changed.
  844. // FALSE - otherwise
  845. //
  846. // Comments:
  847. //
  848. // History: Date Author Comment
  849. // 5/8/00 a-skuzin Created
  850. //
  851. //*************************************************************
  852. typedef BOOL (WINAPI * PCHECKFN)();
  853. BOOL
  854. CRemotePage::OnRemoteEnable()
  855. {
  856. //First check if multiple connections are allowed
  857. DWORD dwAllowMultipleTSSessions = 0;
  858. DWORD dwType;
  859. DWORD cbSize;
  860. LONG Err;
  861. HKEY hKey;
  862. BOOL bResult = TRUE;
  863. //Fast User Switching / Remote Connections and Offline Files should work together fine.
  864. //when Brian Aust makes his changes to offline files.
  865. //therefore we should not restrict remote connections in any case on Professional Machines.
  866. //on server machine however we conntinue to disallow remote connections if Offline files are on.
  867. if(m_bProfessional)
  868. {
  869. return TRUE;
  870. }
  871. //allow user to uncheck the checkbox
  872. if(IsDlgButtonChecked(m_hDlg,IDC_REMOTE_ENABLE) == BST_UNCHECKED )
  873. {
  874. return TRUE;
  875. }
  876. //check if multiple sessions is allowed.
  877. Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  878. TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"),
  879. 0,
  880. KEY_QUERY_VALUE,
  881. &hKey);
  882. if(Err == ERROR_SUCCESS)
  883. {
  884. cbSize = sizeof(DWORD);
  885. Err = RegQueryValueEx(hKey,
  886. TEXT("AllowMultipleTSSessions"),
  887. NULL,
  888. &dwType,
  889. (LPBYTE)&dwAllowMultipleTSSessions,
  890. &cbSize);
  891. if(Err == ERROR_SUCCESS && dwAllowMultipleTSSessions)
  892. {
  893. //multiple sessions is allowed.
  894. //check if CSC (Offline Files) is enabled
  895. HMODULE hLib = LoadLibrary(TEXT("cscdll.dll"));
  896. if(hLib)
  897. {
  898. PCHECKFN pfnCSCIsCSCEnabled = (PCHECKFN)GetProcAddress(hLib,"CSCIsCSCEnabled");
  899. if(pfnCSCIsCSCEnabled && pfnCSCIsCSCEnabled())
  900. {
  901. //Offline Files is enabled
  902. //uncheck the checkbox; show the dialog
  903. COfflineFilesDialog Dlg(m_hInst);
  904. CheckDlgButton(m_hDlg,IDC_REMOTE_ENABLE,BST_UNCHECKED);
  905. Dlg.DoDialog(m_hDlg);
  906. bResult = FALSE;
  907. }
  908. }
  909. FreeLibrary(hLib);
  910. }
  911. RegCloseKey(hKey);
  912. }
  913. return bResult;
  914. }
  915. //*************************************************************
  916. //
  917. // CRemotePage::OnRemoteSelectUsers()
  918. //
  919. // Purpose: Creates "Remote Desktop Users" dialog.
  920. //
  921. // Parameters: NONE
  922. //
  923. // Return: NONE
  924. //
  925. // Comments:
  926. //
  927. // History: Date Author Comment
  928. // 12/27/00 skuzin Created
  929. //
  930. //*************************************************************
  931. void
  932. CRemotePage::OnRemoteSelectUsers()
  933. {
  934. m_RemoteUsersDialog.DoDialog(m_hDlg);
  935. }
  936. //*************************************************************
  937. //
  938. // CRemotePage::RemoteEnableWarning()
  939. //
  940. // Purpose: Displays a message box about empty passwords
  941. // firewalls and other stuff that can prevent
  942. // remote sessions from working properly.
  943. //
  944. // Parameters: NONE
  945. //
  946. // Return: NONE
  947. //
  948. // Comments:
  949. //
  950. // History: Date Author Comment
  951. // 3/28/01 a-skuzin Created
  952. //
  953. //*************************************************************
  954. void
  955. CRemotePage::RemoteEnableWarning()
  956. {
  957. if(IsDlgButtonChecked(m_hDlg,IDC_REMOTE_ENABLE) == BST_CHECKED )
  958. {
  959. //
  960. //Now warn admin about empty passwords.
  961. //Empty passwords are not allowed with
  962. //RemoteInteractive logon.
  963. //
  964. //Allocate a buffer for the string 1000 chars should be enough
  965. //
  966. TCHAR szTitle[MAX_PATH+1];
  967. DWORD cMsg = 1000;
  968. LPTSTR szMsg = (LPTSTR) LocalAlloc(LPTR,(cMsg+1)*sizeof(TCHAR));
  969. if(szMsg)
  970. {
  971. if(LoadString(m_hInst,IDS_WRN_EMPTY_PASSWORD,szMsg,cMsg) &&
  972. LoadString(m_hInst,IDS_REMOTE_SESSIONS,szTitle,MAX_PATH))
  973. {
  974. MessageBox(m_hDlg,szMsg,szTitle,
  975. MB_OK | MB_ICONINFORMATION);
  976. }
  977. LocalFree(szMsg);
  978. }
  979. }
  980. }
  981. //*************************************************************
  982. //
  983. // DisplayError()
  984. //
  985. // Purpose: shows message box with error description
  986. //
  987. // Parameters: ErrID - error code
  988. // MsgID - ID of the first part of error messsage in the string table
  989. // TitleID - ID of the title in the string table
  990. // Return: NONE
  991. //
  992. // Comments:
  993. //
  994. // History: Date Author Comment
  995. // 3/13/00 a-skuzin Created
  996. //
  997. //*************************************************************
  998. void
  999. DisplayError(
  1000. IN HINSTANCE hInst,
  1001. IN HWND hDlg,
  1002. IN UINT ErrID,
  1003. IN UINT MsgID,
  1004. IN UINT TitleID,
  1005. ...)
  1006. {
  1007. TCHAR szTemplate[MAX_PATH+1];
  1008. TCHAR szErr[MAX_PATH+1];
  1009. if(!LoadString(hInst,MsgID,szTemplate,MAX_PATH))
  1010. {
  1011. return;
  1012. }
  1013. va_list arglist;
  1014. va_start(arglist, TitleID);
  1015. wvsprintf(szErr,szTemplate,arglist);
  1016. va_end(arglist);
  1017. TCHAR szTitle[MAX_PATH+1];
  1018. if(!LoadString(hInst,TitleID,szTitle,MAX_PATH))
  1019. {
  1020. return;
  1021. }
  1022. LPTSTR szDescr;
  1023. //load module with network error messages
  1024. HMODULE hNetErrModule=LoadLibraryEx(TEXT("netmsg.dll"),NULL,
  1025. LOAD_LIBRARY_AS_DATAFILE|DONT_RESOLVE_DLL_REFERENCES);
  1026. DWORD dwFlags;
  1027. if(hNetErrModule)
  1028. {
  1029. dwFlags=FORMAT_MESSAGE_FROM_SYSTEM|
  1030. FORMAT_MESSAGE_FROM_HMODULE|
  1031. FORMAT_MESSAGE_ALLOCATE_BUFFER|
  1032. FORMAT_MESSAGE_IGNORE_INSERTS;
  1033. }
  1034. else
  1035. {
  1036. dwFlags=FORMAT_MESSAGE_FROM_SYSTEM|
  1037. FORMAT_MESSAGE_ALLOCATE_BUFFER|
  1038. FORMAT_MESSAGE_IGNORE_INSERTS;
  1039. }
  1040. if(FormatMessage(dwFlags,
  1041. hNetErrModule,
  1042. ErrID,
  1043. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1044. (LPTSTR)&szDescr,
  1045. 0,
  1046. NULL))
  1047. {
  1048. LPTSTR szErrMessage=(LPTSTR)LocalAlloc(LPTR,
  1049. (lstrlen(szErr)+lstrlen(szDescr)+3)*sizeof(TCHAR));
  1050. if(szErrMessage)
  1051. {
  1052. wsprintf(szErrMessage,TEXT("%s\n\n%s"),szErr,szDescr);
  1053. MessageBox(hDlg,szErrMessage,szTitle,MB_OK | MB_ICONSTOP);
  1054. LocalFree(szErrMessage);
  1055. }
  1056. LocalFree(szDescr);
  1057. }
  1058. else
  1059. {
  1060. MessageBox(hDlg,szErr,szTitle,MB_OK | MB_ICONSTOP);
  1061. }
  1062. if(hNetErrModule)
  1063. {
  1064. FreeLibrary(hNetErrModule);
  1065. }
  1066. }
  1067. //*************************************************************
  1068. //
  1069. // getGroupMembershipPickerSettings()
  1070. //
  1071. // Purpose: prepares DSOP_SCOPE_INIT_INFO
  1072. //
  1073. // Parameters: OUT DSOP_SCOPE_INIT_INFO*& infos,
  1074. // OUT ULONG& infoCount
  1075. //
  1076. // Return: FALSE if cannot allocate memory
  1077. //
  1078. // Comments:
  1079. //
  1080. // History: Date Author Comment
  1081. // 3/13/00 a-skuzin Created
  1082. //
  1083. //*************************************************************
  1084. BOOL
  1085. getGroupMembershipPickerSettings(
  1086. OUT DSOP_SCOPE_INIT_INFO*& infos,
  1087. OUT ULONG& infoCount)
  1088. {
  1089. static const int INFO_COUNT = 5;
  1090. infos = new DSOP_SCOPE_INIT_INFO[INFO_COUNT];
  1091. if(infos == NULL)
  1092. {
  1093. infoCount = 0;
  1094. return FALSE;
  1095. }
  1096. infoCount = INFO_COUNT;
  1097. memset(infos, 0, sizeof(DSOP_SCOPE_INIT_INFO) * INFO_COUNT);
  1098. int scope = 0;
  1099. infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  1100. infos[scope].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
  1101. infos[scope].flScope =
  1102. DSOP_SCOPE_FLAG_STARTING_SCOPE
  1103. | DSOP_SCOPE_FLAG_WANT_DOWNLEVEL_BUILTIN_PATH;
  1104. // this is implied for machine only scope
  1105. /* | DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT */
  1106. // allow only local users from the machine scope
  1107. infos[scope].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  1108. infos[scope].FilterFlags.flDownlevel =
  1109. DSOP_DOWNLEVEL_FILTER_USERS;
  1110. // | DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS;
  1111. // for the domain this machine is joined to (native and mixed mode).
  1112. scope++;
  1113. infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  1114. infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  1115. infos[scope].flType =
  1116. DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  1117. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  1118. infos[scope].FilterFlags.Uplevel.flNativeModeOnly =
  1119. DSOP_FILTER_GLOBAL_GROUPS_SE
  1120. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  1121. //| DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE
  1122. | DSOP_FILTER_USERS;
  1123. // here, we allow only domain global groups and domain users. While
  1124. // it is possible to add a domain local group to a machine local group,
  1125. // I'm told such an operation is not really useful from an administraion
  1126. // perspective.
  1127. infos[scope].FilterFlags.Uplevel.flMixedModeOnly =
  1128. DSOP_FILTER_GLOBAL_GROUPS_SE
  1129. | DSOP_FILTER_USERS;
  1130. // same comment above re: domain local groups applies here too.
  1131. infos[scope].FilterFlags.flDownlevel =
  1132. DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS
  1133. | DSOP_DOWNLEVEL_FILTER_USERS;
  1134. // for domains in the same tree (native and mixed mode)
  1135. scope++;
  1136. infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  1137. infos[scope].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
  1138. infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  1139. infos[scope].FilterFlags.Uplevel.flNativeModeOnly =
  1140. DSOP_FILTER_GLOBAL_GROUPS_SE
  1141. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  1142. | DSOP_FILTER_USERS;
  1143. // above domain local group comment applies here, too.
  1144. infos[scope].FilterFlags.Uplevel.flMixedModeOnly =
  1145. DSOP_FILTER_GLOBAL_GROUPS_SE
  1146. | DSOP_FILTER_USERS;
  1147. // for external trusted domains
  1148. scope++;
  1149. infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  1150. infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  1151. infos[scope].flType =
  1152. DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  1153. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
  1154. infos[scope].FilterFlags.Uplevel.flNativeModeOnly =
  1155. DSOP_FILTER_GLOBAL_GROUPS_SE
  1156. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  1157. | DSOP_FILTER_USERS;
  1158. infos[scope].FilterFlags.Uplevel.flMixedModeOnly =
  1159. DSOP_FILTER_GLOBAL_GROUPS_SE
  1160. | DSOP_FILTER_USERS;
  1161. infos[scope].FilterFlags.flDownlevel =
  1162. DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS
  1163. | DSOP_DOWNLEVEL_FILTER_USERS;
  1164. // for the global catalog
  1165. scope++;
  1166. infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  1167. infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  1168. infos[scope].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  1169. // only native mode applies to gc scope.
  1170. infos[scope].FilterFlags.Uplevel.flNativeModeOnly =
  1171. DSOP_FILTER_GLOBAL_GROUPS_SE
  1172. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  1173. | DSOP_FILTER_USERS;
  1174. // SPB:252126 the workgroup scope doesn't apply in this case
  1175. // // for when the machine is not joined to a domain
  1176. // scope++;
  1177. // infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  1178. // infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  1179. // infos[scope].flType = DSOP_SCOPE_TYPE_WORKGROUP;
  1180. //
  1181. // infos[scope].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  1182. // infos[scope].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  1183. _ASSERT(scope == INFO_COUNT - 1);
  1184. return TRUE;
  1185. }
  1186. //*************************************************************
  1187. //
  1188. // VariantToSid()
  1189. //
  1190. // Purpose: Converts a VARIANT containing a safe array
  1191. // of bytes to a SID
  1192. //
  1193. // Parameters: IN VARIANT* var,
  1194. // OUT PSID *ppSid
  1195. //
  1196. // Return:
  1197. //
  1198. // Comments:
  1199. //
  1200. // History: Date Author Comment
  1201. // 3/13/00 a-skuzin Created
  1202. //
  1203. //*************************************************************
  1204. HRESULT
  1205. VariantToSid(
  1206. IN VARIANT* var,
  1207. OUT PSID *ppSid)
  1208. {
  1209. _ASSERT(var);
  1210. _ASSERT(V_VT(var) == (VT_ARRAY | VT_UI1));
  1211. HRESULT hr = S_OK;
  1212. SAFEARRAY* psa = V_ARRAY(var);
  1213. do
  1214. {
  1215. _ASSERT(psa);
  1216. if (!psa)
  1217. {
  1218. hr = E_INVALIDARG;
  1219. break;
  1220. }
  1221. if (SafeArrayGetDim(psa) != 1)
  1222. {
  1223. hr = E_INVALIDARG;
  1224. break;
  1225. }
  1226. if (SafeArrayGetElemsize(psa) != 1)
  1227. {
  1228. hr = E_INVALIDARG;
  1229. break;
  1230. }
  1231. PSID sid = 0;
  1232. hr = SafeArrayAccessData(psa, reinterpret_cast<void**>(&sid));
  1233. if(FAILED(hr))
  1234. {
  1235. break;
  1236. }
  1237. if (!IsValidSid(sid))
  1238. {
  1239. SafeArrayUnaccessData(psa);
  1240. hr = E_INVALIDARG;
  1241. break;
  1242. }
  1243. *ppSid = (PSID) new BYTE[GetLengthSid(sid)];
  1244. if(!(*ppSid))
  1245. {
  1246. SafeArrayUnaccessData(psa);
  1247. hr = E_OUTOFMEMORY;
  1248. break;
  1249. }
  1250. CopySid(GetLengthSid(sid),*ppSid,sid);
  1251. SafeArrayUnaccessData(psa);
  1252. } while (0);
  1253. return hr;
  1254. }
  1255. /*****************************************************************************
  1256. *
  1257. * TestUserForAdmin - Hydrix helper function
  1258. *
  1259. * Returns whether the current thread is running under admin
  1260. * security.
  1261. *
  1262. * ENTRY:
  1263. * NONE
  1264. *
  1265. * EXIT:
  1266. * TRUE/FALSE - whether user is specified admin
  1267. *
  1268. ****************************************************************************/
  1269. BOOL
  1270. TestUserForAdmin()
  1271. {
  1272. BOOL IsMember, IsAnAdmin;
  1273. SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
  1274. PSID AdminSid;
  1275. if (!AllocateAndInitializeSid(&SystemSidAuthority,
  1276. 2,
  1277. SECURITY_BUILTIN_DOMAIN_RID,
  1278. DOMAIN_ALIAS_RID_ADMINS,
  1279. 0, 0, 0, 0, 0, 0,
  1280. &AdminSid))
  1281. {
  1282. IsAnAdmin = FALSE;
  1283. }
  1284. else
  1285. {
  1286. if (!CheckTokenMembership( NULL,
  1287. AdminSid,
  1288. &IsMember))
  1289. {
  1290. FreeSid(AdminSid);
  1291. IsAnAdmin = FALSE;
  1292. }
  1293. else
  1294. {
  1295. FreeSid(AdminSid);
  1296. IsAnAdmin = IsMember;
  1297. }
  1298. }
  1299. return IsAnAdmin;
  1300. }
  1301. //*************************************************************
  1302. //
  1303. // OfflineFilesDlgProc()
  1304. //
  1305. // Purpose: Dialog box procedure for "Disable Offline Files" dialog
  1306. //
  1307. // Parameters: hDlg - handle to the dialog box
  1308. // uMsg - window message
  1309. // wParam - wParam
  1310. // lParam - lParam (if uMsg is WM_INITDIALOG - this is a pointer to
  1311. // object of COfflineFilesDialog class)
  1312. //
  1313. // Return: TRUE if message was processed
  1314. // FALSE if not
  1315. //
  1316. // Comments:
  1317. //
  1318. // History: Date Author Comment
  1319. // 5/9/00 a-skuzin Created
  1320. //
  1321. //*************************************************************
  1322. INT_PTR APIENTRY
  1323. OfflineFilesDlgProc (
  1324. HWND hDlg,
  1325. UINT uMsg,
  1326. WPARAM wParam,
  1327. LPARAM lParam)
  1328. {
  1329. COfflineFilesDialog *pDlg = (COfflineFilesDialog *) GetWindowLongPtr(hDlg, DWLP_USER);
  1330. switch (uMsg)
  1331. {
  1332. case WM_INITDIALOG:
  1333. {
  1334. pDlg=(COfflineFilesDialog *)lParam;
  1335. SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)pDlg);
  1336. if(pDlg)
  1337. {
  1338. pDlg->OnInitDialog(hDlg);
  1339. }
  1340. }
  1341. break;
  1342. case WM_NOTIFY:
  1343. switch (((NMHDR FAR*)lParam)->code)
  1344. {
  1345. case NM_CLICK:
  1346. case NM_RETURN:
  1347. if(pDlg)
  1348. {
  1349. pDlg->OnLink(wParam);
  1350. }
  1351. break;
  1352. default:
  1353. return FALSE;
  1354. }
  1355. break;
  1356. case WM_COMMAND:
  1357. switch(LOWORD(wParam))
  1358. {
  1359. case IDOK:
  1360. case IDCANCEL:
  1361. EndDialog(hDlg,0);
  1362. break;
  1363. default:
  1364. return FALSE;
  1365. }
  1366. default:
  1367. return FALSE;
  1368. }
  1369. return TRUE;
  1370. }
  1371. //*************************************************************
  1372. // class COfflineFilesDialog
  1373. //*************************************************************
  1374. //*************************************************************
  1375. //
  1376. // COfflineFilesDialog::COfflineFilesDialog()
  1377. //
  1378. // Purpose: Constructor
  1379. // Parameters: HINSTANCE hInst
  1380. //
  1381. // Return: NONE
  1382. //
  1383. // Comments:
  1384. //
  1385. // History: Date Author Comment
  1386. // 5/8/00 a-skuzin Created
  1387. //
  1388. //*************************************************************
  1389. COfflineFilesDialog::COfflineFilesDialog(
  1390. IN HINSTANCE hInst)
  1391. : m_hInst(hInst),m_hDlg(NULL)
  1392. {
  1393. }
  1394. //*************************************************************
  1395. //
  1396. // COfflineFilesDialog::DoDialog()
  1397. //
  1398. // Purpose: Creates "Disable Offline Files" dialog
  1399. //
  1400. // Parameters: HWND hwndParent
  1401. //
  1402. // Return:
  1403. //
  1404. // Comments:
  1405. //
  1406. // History: Date Author Comment
  1407. // 5/8/00 a-skuzin Created
  1408. //
  1409. //*************************************************************
  1410. INT_PTR
  1411. COfflineFilesDialog::DoDialog(
  1412. IN HWND hwndParent)
  1413. {
  1414. return DialogBoxParam(
  1415. m_hInst,
  1416. MAKEINTRESOURCE(IDD_DISABLE_OFFLINE_FILES),
  1417. hwndParent,
  1418. OfflineFilesDlgProc,
  1419. (LPARAM) this);
  1420. }
  1421. //*************************************************************
  1422. //
  1423. // COfflineFilesDialog::OnInitDialog()
  1424. //
  1425. // Purpose: Initializes m_hDlg variable
  1426. //
  1427. // Parameters: HWND hDlg
  1428. //
  1429. // Return: NONE
  1430. //
  1431. // Comments:
  1432. //
  1433. // History: Date Author Comment
  1434. // 5/8/00 a-skuzin Created
  1435. //
  1436. //*************************************************************
  1437. void
  1438. COfflineFilesDialog::OnInitDialog(
  1439. IN HWND hDlg)
  1440. {
  1441. m_hDlg = hDlg;
  1442. }
  1443. //*************************************************************
  1444. //
  1445. // COfflineFilesDialog::OnLink()
  1446. //
  1447. // Purpose: If ID of the link is IDC_OFFLINE_FILES
  1448. // it shows "Offline Files" property page.
  1449. //
  1450. // Parameters: WPARAM wParam - ID of the link.
  1451. //
  1452. // Return: NONE
  1453. //
  1454. // Comments:
  1455. //
  1456. // History: Date Author Comment
  1457. // 5/9/00 a-skuzin Created
  1458. //
  1459. //*************************************************************
  1460. typedef DWORD (WINAPI * PFNCSCPROP)(HWND);
  1461. void
  1462. COfflineFilesDialog::OnLink(
  1463. IN WPARAM wParam)
  1464. {
  1465. if(wParam == IDC_OFFLINE_FILES)
  1466. {
  1467. HINSTANCE hLib = LoadLibrary(TEXT("cscui.dll"));
  1468. if (hLib)
  1469. {
  1470. PFNCSCPROP pfnCSCUIOptionsPropertySheet =
  1471. (PFNCSCPROP)GetProcAddress(hLib, "CSCUIOptionsPropertySheet");
  1472. if (pfnCSCUIOptionsPropertySheet)
  1473. {
  1474. pfnCSCUIOptionsPropertySheet(m_hDlg);
  1475. }
  1476. FreeLibrary(hLib);
  1477. }
  1478. }
  1479. }
  1480. //*************************************************************
  1481. // class CRemoteUsersDialog
  1482. //*************************************************************
  1483. //*************************************************************
  1484. //
  1485. // RemoteUsersDlgProc()
  1486. //
  1487. // Purpose: Dialog box procedure for "Remote Desktop Users" dialog
  1488. //
  1489. // Parameters: hDlg - handle to the dialog box
  1490. // uMsg - window message
  1491. // wParam - wParam
  1492. // lParam - lParam (if uMsg is WM_INITDIALOG - this is a pointer to
  1493. // object of CRemoteUsersDialog class)
  1494. //
  1495. // Return: TRUE if message was processed
  1496. // FALSE if not
  1497. //
  1498. // Comments:
  1499. //
  1500. // History: Date Author Comment
  1501. // 12/22/00 skuzin Created
  1502. //
  1503. //*************************************************************
  1504. INT_PTR APIENTRY
  1505. RemoteUsersDlgProc (
  1506. HWND hDlg,
  1507. UINT uMsg,
  1508. WPARAM wParam,
  1509. LPARAM lParam)
  1510. {
  1511. CRemoteUsersDialog *pDlg = (CRemoteUsersDialog *) GetWindowLongPtr(hDlg, DWLP_USER);
  1512. switch (uMsg)
  1513. {
  1514. case WM_INITDIALOG:
  1515. {
  1516. pDlg=(CRemoteUsersDialog *)lParam;
  1517. SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)pDlg);
  1518. if(pDlg)
  1519. {
  1520. pDlg->OnInitDialog(hDlg);
  1521. }
  1522. }
  1523. return TRUE;
  1524. case WM_NOTIFY:
  1525. switch (((NMHDR FAR*)lParam)->code)
  1526. {
  1527. case NM_CLICK:
  1528. case NM_RETURN:
  1529. if(pDlg)
  1530. {
  1531. pDlg->OnLink(wParam);
  1532. }
  1533. return TRUE;
  1534. case LVN_ITEMCHANGED:
  1535. if(pDlg)
  1536. {
  1537. pDlg->OnItemChanged(lParam);
  1538. }
  1539. return TRUE;
  1540. default:
  1541. break;
  1542. }
  1543. break;
  1544. case WM_COMMAND:
  1545. switch(LOWORD(wParam))
  1546. {
  1547. case IDOK:
  1548. if(pDlg)
  1549. {
  1550. pDlg->OnOk();
  1551. }
  1552. EndDialog(hDlg,0);
  1553. break;
  1554. case IDCANCEL:
  1555. EndDialog(hDlg,0);
  1556. break;
  1557. case IDC_REMOTE_USR_ADD:
  1558. if(pDlg)
  1559. {
  1560. pDlg->AddUsers();
  1561. }
  1562. break;
  1563. case IDC_REMOTE_USR_REMOVE:
  1564. if(pDlg)
  1565. {
  1566. pDlg->RemoveUsers();
  1567. }
  1568. break;
  1569. default:
  1570. return FALSE;
  1571. }
  1572. SetWindowLong(hDlg,DWLP_MSGRESULT,0);
  1573. return TRUE;
  1574. case WM_DESTROY:
  1575. if(pDlg)
  1576. {
  1577. pDlg->OnDestroyWindow();
  1578. }
  1579. SetWindowLong(hDlg,DWLP_MSGRESULT,0);
  1580. return TRUE;
  1581. case WM_HELP:
  1582. {
  1583. LPHELPINFO phi=(LPHELPINFO)lParam;
  1584. if(phi && phi->dwContextId)
  1585. {
  1586. WinHelp(hDlg,TEXT("SYSDM.HLP"),HELP_CONTEXTPOPUP,phi->dwContextId);
  1587. SetWindowLong(hDlg,DWLP_MSGRESULT,TRUE);
  1588. return TRUE;
  1589. }
  1590. }
  1591. break;
  1592. case WM_CONTEXTMENU: // right mouse click
  1593. WinHelp((HWND) wParam, TEXT("SYSDM.HLP"), HELP_CONTEXTMENU,
  1594. (DWORD_PTR)aHelpIds);
  1595. return TRUE;
  1596. default:
  1597. break;
  1598. }
  1599. return FALSE;
  1600. }
  1601. //*************************************************************
  1602. //
  1603. // CRemoteUsersDialog::CRemoteUsersDialog()
  1604. //
  1605. // Purpose: Constructor
  1606. // Parameters: HINSTANCE hInst
  1607. //
  1608. // Return: NONE
  1609. //
  1610. // Comments:
  1611. //
  1612. // History: Date Author Comment
  1613. // 12/22/00 skuzin Created
  1614. //
  1615. //*************************************************************
  1616. CRemoteUsersDialog::CRemoteUsersDialog(
  1617. IN HINSTANCE hInst)
  1618. : m_hInst(hInst),m_hDlg(NULL),m_bCanShowDialog(FALSE)
  1619. {
  1620. m_szRemoteGroupName[0] = 0;
  1621. m_szLocalCompName[0] = 0;
  1622. m_hList = NULL;
  1623. m_iLocUser = m_iGlobUser = m_iLocGroup = m_iGlobGroup = m_iUnknown = 0;
  1624. }
  1625. //*************************************************************
  1626. //
  1627. // CRemoteUsersDialog::DoDialog()
  1628. //
  1629. // Purpose: Creates "Remote Desktop Users" dialog
  1630. //
  1631. // Parameters: HWND hwndParent
  1632. //
  1633. // Return:
  1634. //
  1635. // Comments:
  1636. //
  1637. // History: Date Author Comment
  1638. // 12/22/00 a-skuzin Created
  1639. //
  1640. //*************************************************************
  1641. INT_PTR
  1642. CRemoteUsersDialog::DoDialog(
  1643. IN HWND hwndParent)
  1644. {
  1645. if(!m_bCanShowDialog)
  1646. {
  1647. return -1;
  1648. }
  1649. else
  1650. {
  1651. return DialogBoxParam(
  1652. m_hInst,
  1653. MAKEINTRESOURCE(IDD_REMOTE_DESKTOP_USERS),
  1654. hwndParent,
  1655. RemoteUsersDlgProc,
  1656. (LPARAM) this);
  1657. }
  1658. }
  1659. //*************************************************************
  1660. //
  1661. // CRemoteUsersDialog::CanShowDialog()
  1662. //
  1663. // Purpose:
  1664. //
  1665. // Parameters: IN OUT LPBOOL pbAccessDenied - set to TRUE if
  1666. // NetLocalGroupAddMembers returns ACCESS_DENIED.
  1667. //
  1668. // Return:
  1669. //
  1670. // Comments:
  1671. //
  1672. // History: Date Author Comment
  1673. // 12/27/00 skuzin Created
  1674. //
  1675. //*************************************************************
  1676. BOOL
  1677. CRemoteUsersDialog::CanShowDialog(
  1678. IN OUT LPBOOL pbAccessDenied)
  1679. {
  1680. *pbAccessDenied = FALSE;
  1681. //get name of the "Remote Desktop Users" group
  1682. //(it can depend on the language used)
  1683. //first create SID
  1684. SID_IDENTIFIER_AUTHORITY NtSidAuthority = SECURITY_NT_AUTHORITY;
  1685. PSID pSid = NULL;
  1686. if( !AllocateAndInitializeSid(
  1687. &NtSidAuthority,
  1688. 2,
  1689. SECURITY_BUILTIN_DOMAIN_RID,
  1690. DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS,
  1691. 0, 0, 0, 0, 0, 0,
  1692. &pSid
  1693. ))
  1694. {
  1695. return FALSE;
  1696. }
  1697. //Lookup name
  1698. m_szRemoteGroupName[0] = 0;
  1699. DWORD cRemoteGroupName = MAX_PATH;
  1700. WCHAR szDomainName[MAX_PATH+1];
  1701. DWORD cDomainName = MAX_PATH;
  1702. SID_NAME_USE eUse;
  1703. if(!LookupAccountSidW(NULL,pSid,
  1704. m_szRemoteGroupName,&cRemoteGroupName,
  1705. szDomainName,&cDomainName,
  1706. &eUse))
  1707. {
  1708. FreeSid(pSid);
  1709. return FALSE;
  1710. }
  1711. FreeSid(pSid);
  1712. //on the group
  1713. //we trying to add 0 members to the group to see if it returns
  1714. //ACCESS DENIED
  1715. NET_API_STATUS Result= NetLocalGroupAddMembers(NULL,m_szRemoteGroupName,0,NULL,0);
  1716. if(Result == ERROR_ACCESS_DENIED)
  1717. {
  1718. *pbAccessDenied = TRUE;
  1719. }
  1720. m_bCanShowDialog = TRUE;
  1721. return TRUE;
  1722. }
  1723. //*************************************************************
  1724. //
  1725. // CRemoteUsersDialog::OnInitDialog()
  1726. //
  1727. // Purpose: Initializes m_hDlg variable
  1728. //
  1729. // Parameters: HWND hDlg
  1730. //
  1731. // Return: NONE
  1732. //
  1733. // Comments:
  1734. //
  1735. // History: Date Author Comment
  1736. // 5/8/00 a-skuzin Created
  1737. //
  1738. //*************************************************************
  1739. void
  1740. CRemoteUsersDialog::OnInitDialog(
  1741. IN HWND hDlg)
  1742. {
  1743. m_hDlg = hDlg;
  1744. m_szLocalCompName[0] = 0;
  1745. DWORD cCompName = MAX_PATH;
  1746. GetComputerNameW(m_szLocalCompName,&cCompName);
  1747. //fill list of Remote Desktop Users
  1748. m_hList = GetDlgItem(m_hDlg,IDC_REMOTE_USR_LIST);
  1749. if(m_hList)
  1750. {
  1751. //create image list
  1752. HIMAGELIST hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
  1753. GetSystemMetrics(SM_CYSMICON), ILC_MASK , 5, 1);
  1754. if(hImageList)
  1755. {
  1756. HICON hIcon;
  1757. hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_UNKNOWN), IMAGE_ICON,
  1758. 16, 16, 0);
  1759. if (hIcon)
  1760. {
  1761. m_iUnknown = ImageList_AddIcon(hImageList, hIcon);
  1762. DestroyIcon(hIcon);
  1763. }
  1764. hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_LOC_USER), IMAGE_ICON,
  1765. 16, 16, 0);
  1766. if (hIcon)
  1767. {
  1768. m_iLocUser = ImageList_AddIcon(hImageList, hIcon);
  1769. DestroyIcon(hIcon);
  1770. }
  1771. hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_GLOB_USER), IMAGE_ICON,
  1772. 16, 16, 0);
  1773. if (hIcon)
  1774. {
  1775. m_iGlobUser = ImageList_AddIcon(hImageList, hIcon);
  1776. DestroyIcon(hIcon);
  1777. }
  1778. hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_LOC_GROUP), IMAGE_ICON,
  1779. 16, 16, 0);
  1780. if (hIcon)
  1781. {
  1782. m_iLocGroup = ImageList_AddIcon(hImageList, hIcon);
  1783. DestroyIcon(hIcon);
  1784. }
  1785. hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_GLOB_GROUP), IMAGE_ICON,
  1786. 16, 16, 0);
  1787. if (hIcon)
  1788. {
  1789. m_iGlobGroup = ImageList_AddIcon(hImageList, hIcon);
  1790. DestroyIcon(hIcon);
  1791. }
  1792. ListView_SetImageList(m_hList,hImageList,LVSIL_SMALL);
  1793. }
  1794. ReloadList();
  1795. }
  1796. //If current user already has remote logon access,
  1797. //remind it to him by showing corresponding text in the dialog.
  1798. InitAccessMessage();
  1799. }
  1800. //*************************************************************
  1801. //
  1802. // CRemoteUsersDialog::OnLink()
  1803. //
  1804. // Purpose:
  1805. //
  1806. // Parameters: WPARAM wParam - ID of the link.
  1807. //
  1808. // Return: NONE
  1809. //
  1810. // Comments:
  1811. //
  1812. // History: Date Author Comment
  1813. // 5/9/00 a-skuzin Created
  1814. //
  1815. //*************************************************************
  1816. void
  1817. CRemoteUsersDialog::OnLink(
  1818. IN WPARAM wParam)
  1819. {
  1820. switch(wParam)
  1821. {
  1822. case IDC_REMOTE_UPLINK:
  1823. ShellExecute(NULL,TEXT("open"),TEXT("control"),TEXT("userpasswords"),NULL,SW_SHOW);
  1824. break;
  1825. default:
  1826. break;
  1827. }
  1828. }
  1829. //*************************************************************
  1830. //
  1831. // CRemoteUsersDialog::OnOk()
  1832. //
  1833. // Purpose:
  1834. //
  1835. // Parameters: NONE
  1836. //
  1837. // Return: TRUE if success
  1838. //
  1839. // Comments:
  1840. //
  1841. // History: Date Author Comment
  1842. // 12/27/00 skuzin Created
  1843. //
  1844. //*************************************************************
  1845. BOOL
  1846. CRemoteUsersDialog::OnOk()
  1847. {
  1848. if(m_hList)
  1849. {
  1850. //Apply members
  1851. LOCALGROUP_MEMBERS_INFO_0 *plmi0 = NULL;
  1852. DWORD entriesread;
  1853. DWORD totalentries;
  1854. NET_API_STATUS Result;
  1855. Result = NetLocalGroupGetMembers(NULL,m_szRemoteGroupName,0,(LPBYTE *)&plmi0,
  1856. MAX_PREFERRED_LENGTH,&entriesread,&totalentries,NULL);
  1857. if(Result == NERR_Success)
  1858. {
  1859. int j;
  1860. LOCALGROUP_MEMBERS_INFO_0 lmi0;
  1861. LVITEM lvi;
  1862. lvi.iSubItem = 0;
  1863. lvi.mask = LVIF_PARAM ;
  1864. int iItems=ListView_GetItemCount(m_hList);
  1865. BOOL *pbDoNotAdd = new BOOL[iItems];
  1866. if(!pbDoNotAdd)
  1867. {
  1868. if(plmi0)
  1869. {
  1870. NetApiBufferFree(plmi0);
  1871. }
  1872. //not enough memory - too bad
  1873. return TRUE;
  1874. }
  1875. ZeroMemory(pbDoNotAdd,iItems*sizeof(BOOL));
  1876. for(DWORD i=0;i<entriesread;i++)
  1877. {
  1878. j = FindItemBySid(plmi0[i].lgrmi0_sid);
  1879. //SID was not found in the list - delete member
  1880. if(j == -1)
  1881. {
  1882. lmi0.lgrmi0_sid = plmi0[i].lgrmi0_sid;
  1883. Result = NetLocalGroupDelMembers(NULL,m_szRemoteGroupName,0,(LPBYTE)&lmi0,1);
  1884. if(Result !=NERR_Success)
  1885. {
  1886. delete pbDoNotAdd;
  1887. NetApiBufferFree(plmi0);
  1888. DisplayError(m_hInst, m_hDlg, Result, IDS_ERR_SAVE_MEMBERS, IDS_REMOTE_SESSIONS,
  1889. m_szRemoteGroupName, m_szLocalCompName);
  1890. return FALSE;
  1891. }
  1892. }
  1893. else
  1894. {
  1895. pbDoNotAdd[j] = TRUE;
  1896. }
  1897. }
  1898. //Add the rest of members to the group
  1899. for(j=0;j<iItems;j++)
  1900. {
  1901. if(!pbDoNotAdd[j])
  1902. {
  1903. lvi.iItem = j;
  1904. ListView_GetItem( m_hList, &lvi );
  1905. lmi0.lgrmi0_sid = (PSID) lvi.lParam;
  1906. Result = NetLocalGroupAddMembers(NULL,m_szRemoteGroupName,0,(LPBYTE)&lmi0,1);
  1907. if(Result !=NERR_Success)
  1908. {
  1909. delete pbDoNotAdd;
  1910. NetApiBufferFree(plmi0);
  1911. DisplayError(m_hInst, m_hDlg, Result, IDS_ERR_SAVE_MEMBERS, IDS_REMOTE_SESSIONS,
  1912. m_szRemoteGroupName, m_szLocalCompName);
  1913. return FALSE;
  1914. }
  1915. }
  1916. }
  1917. delete pbDoNotAdd;
  1918. NetApiBufferFree(plmi0);
  1919. }
  1920. else
  1921. {
  1922. DisplayError(m_hInst, m_hDlg, Result, IDS_ERR_SAVE_MEMBERS, IDS_REMOTE_SESSIONS,
  1923. m_szRemoteGroupName, m_szLocalCompName);
  1924. return FALSE;
  1925. }
  1926. return TRUE;
  1927. }
  1928. return FALSE;
  1929. }
  1930. //*************************************************************
  1931. //
  1932. // CRemoteUsersDialog::OnItemChanged()
  1933. //
  1934. // Purpose: Enables or disables "Remove" button.
  1935. //
  1936. // Parameters: lParam -
  1937. //
  1938. // Return: NONE
  1939. //
  1940. // Comments: in case of error shows message box
  1941. //
  1942. // History: Date Author Comment
  1943. // 12/27/00 skuzin Created
  1944. //
  1945. //*************************************************************
  1946. void
  1947. CRemoteUsersDialog::OnItemChanged(
  1948. LPARAM lParam)
  1949. {
  1950. NMLISTVIEW* lv = reinterpret_cast<NMLISTVIEW*>(lParam);
  1951. if (lv->uChanged & LVIF_STATE)
  1952. {
  1953. // a list item changed state
  1954. BOOL selected = ListView_GetSelectedCount(m_hList) > 0;
  1955. EnableWindow(GetDlgItem(m_hDlg, IDC_REMOTE_USR_REMOVE), selected);
  1956. //If we disabled IDC_REMOTE_USR_REMOVE button while it had focus
  1957. //all property page loses focus so "Tab" key does not
  1958. //work anymore. We need to restore focus.
  1959. if(!GetFocus())
  1960. {
  1961. SetFocus(m_hDlg);
  1962. }
  1963. }
  1964. }
  1965. //*************************************************************
  1966. //
  1967. // CRemoteUsersDialog::OnDestroyWindow()
  1968. //
  1969. // Purpose: Frees memory allocated by member's SIDs
  1970. //
  1971. // Parameters: NONE
  1972. //
  1973. // Return: NONE
  1974. //
  1975. // Comments:
  1976. //
  1977. // History: Date Author Comment
  1978. // 12/27/00 skuzin Created
  1979. //
  1980. //*************************************************************
  1981. void
  1982. CRemoteUsersDialog::OnDestroyWindow()
  1983. {
  1984. if(m_hList)
  1985. {
  1986. int iItems=ListView_GetItemCount(m_hList);
  1987. LVITEM lvi;
  1988. lvi.iSubItem = 0;
  1989. lvi.mask = LVIF_PARAM;
  1990. while(iItems)
  1991. {
  1992. lvi.iItem = 0;
  1993. ListView_GetItem( m_hList, &lvi );
  1994. //delete item
  1995. ListView_DeleteItem(m_hList, 0);
  1996. if(lvi.lParam)
  1997. {
  1998. delete (LPVOID)lvi.lParam;
  1999. }
  2000. iItems--; //decrease item count
  2001. }
  2002. }
  2003. }
  2004. //*************************************************************
  2005. //
  2006. // CRemoteUsersDialog::AddUsers()
  2007. //
  2008. // Purpose: adds users to the list
  2009. //
  2010. // Parameters: NONE
  2011. //
  2012. // Return: NONE
  2013. //
  2014. // Comments:
  2015. //
  2016. // History: Date Author Comment
  2017. // 12/27/00 skuzin Created
  2018. //
  2019. //*************************************************************
  2020. void
  2021. CRemoteUsersDialog::AddUsers()
  2022. {
  2023. HRESULT hr = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
  2024. if(SUCCEEDED(hr))
  2025. {
  2026. IDsObjectPicker *pDsObjectPicker = NULL;
  2027. hr = CoCreateInstance(CLSID_DsObjectPicker,
  2028. NULL,
  2029. CLSCTX_INPROC_SERVER,
  2030. IID_IDsObjectPicker,
  2031. (void **) &pDsObjectPicker);
  2032. if(SUCCEEDED(hr))
  2033. {
  2034. DSOP_INIT_INFO initInfo;
  2035. memset(&initInfo, 0, sizeof(initInfo));
  2036. initInfo.cbSize = sizeof(initInfo);
  2037. initInfo.flOptions = DSOP_FLAG_MULTISELECT;
  2038. // aliasing the computerName internal pointer here -- ok, as lifetime
  2039. // of computerName > initInfo
  2040. initInfo.pwzTargetComputer = NULL;
  2041. initInfo.cAttributesToFetch = 1;
  2042. PWSTR attrs[2] = {0, 0};
  2043. attrs[0] = L"ObjectSID";
  2044. // obtuse notation required to cast *in* const and away the static len
  2045. initInfo.apwzAttributeNames = const_cast<PCWSTR*>(&attrs[0]);
  2046. if(getGroupMembershipPickerSettings(initInfo.aDsScopeInfos, initInfo.cDsScopeInfos))
  2047. {
  2048. IDataObject* pdo = NULL;
  2049. if(SUCCEEDED(pDsObjectPicker->Initialize(&initInfo)) &&
  2050. pDsObjectPicker->InvokeDialog(m_hDlg, &pdo) == S_OK &&
  2051. pdo )
  2052. {
  2053. CWaitCursor wait;
  2054. static const UINT cf = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  2055. FORMATETC formatetc =
  2056. {
  2057. (CLIPFORMAT)cf,
  2058. 0,
  2059. DVASPECT_CONTENT,
  2060. -1,
  2061. TYMED_HGLOBAL
  2062. };
  2063. STGMEDIUM stgmedium =
  2064. {
  2065. TYMED_HGLOBAL,
  2066. 0
  2067. };
  2068. if(cf && SUCCEEDED(pdo->GetData(&formatetc, &stgmedium)))
  2069. {
  2070. PVOID lockedHGlobal = GlobalLock(stgmedium.hGlobal);
  2071. DS_SELECTION_LIST* selections =
  2072. reinterpret_cast<DS_SELECTION_LIST*>(lockedHGlobal);
  2073. AddPickerItems(selections);
  2074. GlobalUnlock(stgmedium.hGlobal);
  2075. }
  2076. pdo->Release();
  2077. }
  2078. delete initInfo.aDsScopeInfos;
  2079. }
  2080. pDsObjectPicker->Release();
  2081. }
  2082. CoUninitialize();
  2083. }
  2084. }
  2085. //*************************************************************
  2086. //
  2087. // CRemoteUsersDialog::RemoveUsers()
  2088. //
  2089. // Purpose: Removes users from the list
  2090. //
  2091. // Parameters: NONE
  2092. //
  2093. // Return: NONE
  2094. //
  2095. // Comments:
  2096. //
  2097. // History: Date Author Comment
  2098. // 12/27/00 skuzin Created
  2099. //
  2100. //*************************************************************
  2101. void
  2102. CRemoteUsersDialog::RemoveUsers()
  2103. {
  2104. //delete all selected items
  2105. if(m_hList)
  2106. {
  2107. int iItems=ListView_GetItemCount(m_hList);
  2108. UINT uiState=0;
  2109. int i=0;
  2110. LVITEM lvi;
  2111. lvi.iSubItem = 0;
  2112. lvi.mask = LVIF_STATE | LVIF_PARAM;
  2113. lvi.stateMask = LVIS_SELECTED;
  2114. while(i<iItems)
  2115. {
  2116. lvi.iItem = i;
  2117. ListView_GetItem( m_hList, &lvi );
  2118. if(lvi.state&LVIS_SELECTED)
  2119. {
  2120. //delete item
  2121. ListView_DeleteItem(m_hList, i);
  2122. if(lvi.lParam)
  2123. {
  2124. delete (LPVOID)lvi.lParam;
  2125. }
  2126. iItems--; //decrease item count
  2127. }
  2128. else
  2129. {
  2130. i++;
  2131. }
  2132. }
  2133. //If list is not empty, set focus on the first item.
  2134. if( ListView_GetItemCount(m_hList) )
  2135. {
  2136. ListView_SetItemState(m_hList, 0, LVIS_FOCUSED, LVIS_FOCUSED );
  2137. }
  2138. }
  2139. }
  2140. //*************************************************************
  2141. //
  2142. // CRemoteUsersDialog::IsLocal()
  2143. //
  2144. // Purpose:
  2145. //
  2146. // Parameters: wszDomainandname - domain\user
  2147. // determines whether the user is local or not
  2148. // if local - cuts out domain name
  2149. //
  2150. // Return: NONE
  2151. //
  2152. // Comments:
  2153. //
  2154. // History: Date Author Comment
  2155. // 12/27/00 skuzin Created
  2156. //
  2157. //*************************************************************
  2158. BOOL
  2159. CRemoteUsersDialog::IsLocal(
  2160. LPWSTR wszDomainandname)
  2161. {
  2162. LPWSTR wszTmp = wcschr(wszDomainandname,L'\\');
  2163. if(!wszTmp)
  2164. {
  2165. return TRUE;
  2166. }
  2167. if(!_wcsnicmp(wszDomainandname, m_szLocalCompName,wcslen(m_szLocalCompName) ))
  2168. {
  2169. //get rid of useless domain name
  2170. wcscpy(wszDomainandname,wszTmp+1);
  2171. return TRUE;
  2172. }
  2173. return FALSE;
  2174. }
  2175. //*************************************************************
  2176. //
  2177. // CRemoteUsersDialog::AddPickerItems()
  2178. //
  2179. // Purpose: adds items, returned by DSObjectPicker
  2180. // to the list
  2181. //
  2182. // Parameters: IN DS_SELECTION_LIST *selections
  2183. //
  2184. // Return: NONE
  2185. //
  2186. // Comments:
  2187. //
  2188. // History: Date Author Comment
  2189. // 12/27/00 skuzin Created
  2190. //
  2191. //*************************************************************
  2192. void
  2193. CRemoteUsersDialog::AddPickerItems(
  2194. IN DS_SELECTION_LIST *selections)
  2195. {
  2196. if(!selections)
  2197. {
  2198. return;
  2199. }
  2200. DS_SELECTION* current = &(selections->aDsSelection[0]);
  2201. if(m_hList)
  2202. {
  2203. for (ULONG i = 0; i < selections->cItems; i++, current++)
  2204. {
  2205. // extract the ObjectSID of the object (this should always be
  2206. // present)
  2207. PSID pSid;
  2208. HRESULT hr = VariantToSid(&current->pvarFetchedAttributes[0],&pSid);
  2209. if( SUCCEEDED(hr) )
  2210. {
  2211. //This SID is not in the list
  2212. //Let's add it.
  2213. if(FindItemBySid(pSid) == -1)
  2214. {
  2215. LPWSTR szFullName = NULL;
  2216. SID_NAME_USE eUse;
  2217. LVITEM item;
  2218. ZeroMemory(&item,sizeof(item));
  2219. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  2220. //put SID it into the item data
  2221. //the allocated memory will be freed in OnDestroyWindow()
  2222. item.lParam = (LPARAM)pSid;
  2223. if(LookupSid(pSid,&szFullName, &eUse))
  2224. {
  2225. item.pszText = szFullName;
  2226. }
  2227. else
  2228. {
  2229. eUse = SidTypeUnknown;
  2230. if(current->pwzName)
  2231. {
  2232. item.pszText = current->pwzName;
  2233. }
  2234. else
  2235. {
  2236. item.pszText = L"?";
  2237. }
  2238. }
  2239. switch(eUse)
  2240. {
  2241. case SidTypeUser:
  2242. item.iImage = IsLocal(szFullName) ? m_iLocUser : m_iGlobUser;
  2243. break;
  2244. case SidTypeGroup:
  2245. item.iImage = IsLocal(szFullName) ? m_iLocGroup : m_iGlobGroup;
  2246. break;
  2247. case SidTypeWellKnownGroup:
  2248. item.iImage = m_iLocGroup;
  2249. break;
  2250. default:
  2251. item.iImage = m_iUnknown;
  2252. break;
  2253. }
  2254. if(ListView_InsertItem(m_hList,&item) == -1)
  2255. {
  2256. delete pSid;
  2257. }
  2258. if(szFullName)
  2259. {
  2260. LocalFree(szFullName);
  2261. }
  2262. }
  2263. else
  2264. {
  2265. //Free allocated memory
  2266. delete pSid;
  2267. }
  2268. }
  2269. }
  2270. }
  2271. }
  2272. //*************************************************************
  2273. //
  2274. // CRemoteUsersDialog::FindItemBySid()
  2275. //
  2276. // Purpose: finds user with particular SID in the list
  2277. //
  2278. // Parameters: pSid - SID to find
  2279. //
  2280. // Return: item index (-1 if not found)
  2281. //
  2282. // Comments:
  2283. //
  2284. // History: Date Author Comment
  2285. // 12/27/00 skuzin Created
  2286. //
  2287. //*************************************************************
  2288. int
  2289. CRemoteUsersDialog::FindItemBySid(
  2290. IN PSID pSid)
  2291. {
  2292. if(m_hList)
  2293. {
  2294. LVITEM lvi;
  2295. lvi.iSubItem = 0;
  2296. lvi.mask = LVIF_PARAM ;
  2297. int iItems=ListView_GetItemCount(m_hList);
  2298. for(int i=0;i<iItems;i++)
  2299. {
  2300. lvi.iItem = i;
  2301. ListView_GetItem( m_hList, &lvi );
  2302. PSID pItemSid = (PSID) lvi.lParam;
  2303. if(pItemSid && EqualSid(pSid,pItemSid))
  2304. {
  2305. return i;
  2306. }
  2307. }
  2308. }
  2309. return -1;
  2310. }
  2311. //*************************************************************
  2312. //
  2313. // CRemoteUsersDialog::ReloadList()
  2314. //
  2315. // Purpose: delete all items and then refill it with
  2316. // names of members of "Remote Desktop Users" group.
  2317. //
  2318. // Parameters: NONE
  2319. //
  2320. // Return: NONE
  2321. //
  2322. // Comments:
  2323. //
  2324. // History: Date Author Comment
  2325. // 12/27/00 skuzin Created
  2326. //
  2327. //*************************************************************
  2328. void
  2329. CRemoteUsersDialog::ReloadList()
  2330. {
  2331. if(m_hList)
  2332. {
  2333. CWaitCursor wait;
  2334. //first delete all items
  2335. int iItems=ListView_GetItemCount(m_hList);
  2336. LVITEM item;
  2337. item.iSubItem = 0;
  2338. item.mask = LVIF_PARAM;
  2339. while(iItems)
  2340. {
  2341. item.iItem = 0;
  2342. ListView_GetItem( m_hList, &item );
  2343. //delete item
  2344. ListView_DeleteItem(m_hList, 0);
  2345. if(item.lParam)
  2346. {
  2347. delete (LPVOID)item.lParam;
  2348. }
  2349. iItems--; //decrease item count
  2350. }
  2351. LOCALGROUP_MEMBERS_INFO_2 *plmi2;
  2352. DWORD entriesread;
  2353. DWORD totalentries;
  2354. NET_API_STATUS Result;
  2355. Result = NetLocalGroupGetMembers(NULL,m_szRemoteGroupName,2,(LPBYTE *)&plmi2,
  2356. MAX_PREFERRED_LENGTH,&entriesread,&totalentries,NULL);
  2357. if(Result == NERR_Success || Result == ERROR_MORE_DATA )
  2358. {
  2359. for(DWORD i=0;i<entriesread;i++)
  2360. {
  2361. ZeroMemory(&item,sizeof(item));
  2362. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  2363. item.pszText = plmi2[i].lgrmi2_domainandname;
  2364. //create copy of the SID and put it in item data
  2365. PSID pSid = (PSID)new BYTE[GetLengthSid(plmi2[i].lgrmi2_sid)];
  2366. if(pSid)
  2367. {
  2368. CopySid(GetLengthSid(plmi2[i].lgrmi2_sid),pSid,plmi2[i].lgrmi2_sid);
  2369. item.lParam = (LPARAM)pSid;
  2370. }
  2371. switch(plmi2[i].lgrmi2_sidusage)
  2372. {
  2373. case SidTypeUser:
  2374. item.iImage = IsLocal(plmi2[i].lgrmi2_domainandname) ? m_iLocUser : m_iGlobUser;
  2375. break;
  2376. case SidTypeGroup:
  2377. item.iImage = IsLocal(plmi2[i].lgrmi2_domainandname) ? m_iLocGroup : m_iGlobGroup;
  2378. break;
  2379. case SidTypeWellKnownGroup:
  2380. item.iImage = m_iLocGroup;
  2381. break;
  2382. default:
  2383. item.iImage = m_iUnknown;
  2384. break;
  2385. }
  2386. if(ListView_InsertItem(m_hList,&item) == -1)
  2387. {
  2388. if(pSid)
  2389. {
  2390. delete pSid;
  2391. }
  2392. }
  2393. }
  2394. NetApiBufferFree(plmi2);
  2395. }
  2396. //If list is not empty, set focus on the first item.
  2397. if( ListView_GetItemCount(m_hList) )
  2398. {
  2399. ListView_SetItemState(m_hList, 0, LVIS_FOCUSED, LVIS_FOCUSED );
  2400. }
  2401. }
  2402. }
  2403. //*************************************************************
  2404. //
  2405. // CRemoteUsersDialog::InitAccessMessage()
  2406. //
  2407. // Purpose: Check if current user has remote logon access
  2408. // and if he does, show corresponding text in the dialog.
  2409. //
  2410. // Parameters: NONE
  2411. //
  2412. // Return: NONE
  2413. //
  2414. // Comments:
  2415. //
  2416. // History: Date Author Comment
  2417. // 01/04/01 skuzin Created
  2418. //
  2419. //*************************************************************
  2420. void
  2421. CRemoteUsersDialog::InitAccessMessage()
  2422. {
  2423. //First, get token handle
  2424. HANDLE hToken = NULL, hToken1 = NULL;
  2425. //Get Primary token
  2426. if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE , &hToken))
  2427. {
  2428. return;
  2429. }
  2430. //Get Impersonation token
  2431. if(!DuplicateToken(hToken, SecurityIdentification, &hToken1))
  2432. {
  2433. CloseHandle(hToken);
  2434. return;
  2435. }
  2436. CloseHandle(hToken);
  2437. //Get RDP-Tcp WinStation security descriptor.
  2438. PSECURITY_DESCRIPTOR pSD;
  2439. if(GetRDPSecurityDescriptor(&pSD))
  2440. {
  2441. if(CheckWinstationLogonAccess(hToken1,pSD))
  2442. {
  2443. //Extract the name of the user from the token.
  2444. LPWSTR szName = NULL;
  2445. if(GetTokenUserName(hToken1,&szName))
  2446. {
  2447. //If user is local, remove domain name
  2448. IsLocal(szName);
  2449. //Assemble a text for the message.
  2450. WCHAR szTemplate[MAX_PATH+1];
  2451. HWND hMessage = GetDlgItem(m_hDlg,IDC_USER_HAS_ACCESS);
  2452. if(hMessage &&
  2453. LoadString(m_hInst,IDS_USER_HAS_ASSESS,szTemplate,MAX_PATH))
  2454. {
  2455. LPWSTR szMessage = (LPWSTR) LocalAlloc(LPTR,
  2456. (wcslen(szTemplate)+wcslen(szName))*sizeof(WCHAR));
  2457. if(szMessage)
  2458. {
  2459. wsprintf(szMessage,szTemplate,szName);
  2460. SetWindowText(hMessage,szMessage);
  2461. LocalFree(szMessage);
  2462. }
  2463. }
  2464. LocalFree(szName);
  2465. }
  2466. }
  2467. LocalFree(pSD);
  2468. }
  2469. CloseHandle(hToken1);
  2470. }
  2471. //*************************************************************
  2472. //
  2473. // GetTokenUserName()
  2474. //
  2475. // Purpose: Extracts a user name from the token.
  2476. //
  2477. // Parameters: IN HANDLE hToken
  2478. // OUT LPWSTR *ppName
  2479. //
  2480. // Return: TRUE - if success
  2481. // FALSE - in case of any error
  2482. //
  2483. // Comments: Caller should free memory allocated for user name
  2484. // using LocalFree function
  2485. //
  2486. // History: Date Author Comment
  2487. // 01/04/01 skuzin Created
  2488. //
  2489. //*************************************************************
  2490. BOOL
  2491. GetTokenUserName(
  2492. IN HANDLE hToken,
  2493. OUT LPWSTR *ppName)
  2494. {
  2495. *ppName = NULL;
  2496. DWORD dwReturnLength=0;
  2497. BOOL bResult = FALSE;
  2498. PTOKEN_USER pTUser = NULL;
  2499. if(!GetTokenInformation(hToken,TokenUser,NULL,0,&dwReturnLength) &&
  2500. GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
  2501. dwReturnLength)
  2502. {
  2503. pTUser = (PTOKEN_USER)LocalAlloc(LPTR,dwReturnLength);
  2504. if(pTUser)
  2505. {
  2506. if(GetTokenInformation(hToken,TokenUser,pTUser,dwReturnLength,&dwReturnLength))
  2507. {
  2508. //Get current user 's name.
  2509. LPWSTR szName = NULL;
  2510. SID_NAME_USE eUse;
  2511. return LookupSid(pTUser->User.Sid,ppName,&eUse);
  2512. }
  2513. LocalFree(pTUser);
  2514. }
  2515. }
  2516. return FALSE;
  2517. }
  2518. //*************************************************************
  2519. //
  2520. // GetRDPSecurityDescriptor()
  2521. //
  2522. // Purpose: Returns security descriptor for RDP-Tcp
  2523. //
  2524. // Parameters: OUT PSECURITY_DESCRIPTOR *ppSD
  2525. //
  2526. // Return: TRUE - if success
  2527. // FALSE - in case of any error
  2528. //
  2529. // Comments: Caller should free memory allocated for
  2530. // security descriptor using LocalFree function
  2531. //
  2532. // History: Date Author Comment
  2533. // 01/04/01 skuzin Created
  2534. //
  2535. //*************************************************************
  2536. BOOL
  2537. GetRDPSecurityDescriptor(
  2538. OUT PSECURITY_DESCRIPTOR *ppSD)
  2539. {
  2540. *ppSD = NULL;
  2541. if( FAILED( CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) ) )
  2542. {
  2543. return FALSE;
  2544. }
  2545. ICfgComp *pCfgcomp;
  2546. if( SUCCEEDED( CoCreateInstance( CLSID_CfgComp , NULL , CLSCTX_INPROC_SERVER ,
  2547. IID_ICfgComp , ( LPVOID *)&pCfgcomp ) ) )
  2548. {
  2549. LONG lSDsize;
  2550. PSECURITY_DESCRIPTOR pSD = NULL;
  2551. if( SUCCEEDED( pCfgcomp->Initialize() ) &&
  2552. SUCCEEDED( pCfgcomp->GetSecurityDescriptor( L"RDP-Tcp" , &lSDsize , &pSD ) ) )
  2553. {
  2554. *ppSD = pSD;
  2555. }
  2556. pCfgcomp->Release();
  2557. }
  2558. CoUninitialize();
  2559. return (*ppSD != NULL);
  2560. }
  2561. //*************************************************************
  2562. //
  2563. // CheckWinstationLogonAccess()
  2564. //
  2565. // Purpose: Tests access token for LOGON access to WinStation
  2566. //
  2567. // Parameters: IN HANDLE hToken
  2568. // IN PSECURITY_DESCRIPTOR pSD
  2569. //
  2570. // Return: TRUE - if user has access
  2571. // FALSE - in case of any error or if user
  2572. // does not have access
  2573. //
  2574. // Comments:
  2575. //
  2576. // History: Date Author Comment
  2577. // 01/04/01 skuzin Created
  2578. //
  2579. //*************************************************************
  2580. BOOL
  2581. CheckWinstationLogonAccess(
  2582. IN HANDLE hToken,
  2583. IN PSECURITY_DESCRIPTOR pSD)
  2584. {
  2585. //this is taken from "termsrv\winsta\server\acl.c"
  2586. //
  2587. // Structure that describes the mapping of generic access rights to object
  2588. // specific access rights for Window Station objects.
  2589. //
  2590. GENERIC_MAPPING WinStaMapping = {
  2591. STANDARD_RIGHTS_READ |
  2592. WINSTATION_QUERY,
  2593. STANDARD_RIGHTS_WRITE |
  2594. WINSTATION_SET,
  2595. STANDARD_RIGHTS_EXECUTE,
  2596. WINSTATION_ALL_ACCESS
  2597. };
  2598. PRIVILEGE_SET PrivilegeSet;
  2599. //There are no privileges used for this access check
  2600. //so we don't need to allocate additional memory
  2601. DWORD dwPrivilegeSetLength = sizeof(PrivilegeSet);
  2602. DWORD dwGrantedAccess = 0;
  2603. BOOL bAccessStatus = FALSE;
  2604. if(!AccessCheck(
  2605. pSD, // SD
  2606. hToken, // handle to client access token
  2607. WINSTATION_LOGON, // requested access rights
  2608. &WinStaMapping, // mapping
  2609. &PrivilegeSet, // privileges
  2610. &dwPrivilegeSetLength, // size of privileges buffer
  2611. &dwGrantedAccess, // granted access rights
  2612. &bAccessStatus // result of access check
  2613. ) || !bAccessStatus )
  2614. {
  2615. return FALSE;
  2616. }
  2617. return TRUE;
  2618. }
  2619. //*************************************************************
  2620. //
  2621. // LookupSid()
  2622. //
  2623. // Purpose: Given SID allocates and returns string containing
  2624. // name of the user in format DOMAINNAME\USERNAME
  2625. //
  2626. // Parameters: IN PSID pSid
  2627. // OUT LPWSTR ppName
  2628. // OUT SID_NAME_USE *peUse
  2629. //
  2630. // Return: TRUE if success, FALSE otherwise
  2631. //
  2632. // Comments:
  2633. //
  2634. // History: Date Author Comment
  2635. // 10/23/00 skuzin Created
  2636. //
  2637. //*************************************************************
  2638. BOOL
  2639. LookupSid(
  2640. IN PSID pSid,
  2641. OUT LPWSTR *ppName,
  2642. OUT SID_NAME_USE *peUse)
  2643. {
  2644. LPWSTR szName = NULL;
  2645. DWORD cName = 0;
  2646. LPWSTR szDomainName = NULL;
  2647. DWORD cDomainName = 0;
  2648. *ppName = NULL;
  2649. if(!LookupAccountSidW(NULL,pSid,
  2650. szName,&cName,
  2651. szDomainName,&cDomainName,
  2652. peUse) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  2653. {
  2654. //cName and cDomainName include terminating 0
  2655. *ppName = (LPWSTR)LocalAlloc(LPTR,(cName+cDomainName)*sizeof(WCHAR));
  2656. if(*ppName)
  2657. {
  2658. szDomainName = *ppName;
  2659. szName = &(*ppName)[cDomainName];
  2660. if(LookupAccountSidW(NULL,pSid,
  2661. szName,&cName,
  2662. szDomainName,&cDomainName,
  2663. peUse))
  2664. {
  2665. //user name now in format DOMAINNAME\0USERNAME
  2666. //let's replace '\0' with '\\'
  2667. //now cName and cDomainName do not include terminating 0
  2668. //very confusing
  2669. if(cDomainName)
  2670. {
  2671. (*ppName)[cDomainName] = L'\\';
  2672. }
  2673. return TRUE;
  2674. }
  2675. else
  2676. {
  2677. LocalFree(*ppName);
  2678. *ppName = NULL;
  2679. }
  2680. }
  2681. }
  2682. return FALSE;
  2683. }