Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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