3076 lines
80 KiB
C++
3076 lines
80 KiB
C++
//
|
|
// Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
//
|
|
//
|
|
//==============================================================;
|
|
|
|
#include "RemotePage.h"
|
|
#include <lm.h>
|
|
#include <crtdbg.h>
|
|
#include <shellapi.h>
|
|
#include <htmlhelp.h>
|
|
#include "resource.h"
|
|
#include <shgina.h>
|
|
#include "RAssistance.h"
|
|
#include "RAssistance_i.c"
|
|
#include <winsta.h>
|
|
#include "cfgbkend.h"
|
|
#include "cfgbkend_i.c"
|
|
|
|
extern ULONG g_uObjects;
|
|
|
|
IRASettingProperty* g_praSetting = NULL; // Used for Remote assistance setting
|
|
|
|
#define NO_HELP ((DWORD) -1) // Disables Help for a control
|
|
//Table of help IDs for each control
|
|
DWORD aHelpIds[] = {
|
|
IDC_REMOTE_ENABLE, HIDC_REMOTE_ENABLE,
|
|
IDC_REMOTE_USR_LIST, HIDC_REMOTE_USR_LIST,
|
|
IDC_REMOTE_USR_ADD, HIDC_REMOTE_USR_ADD,
|
|
IDC_REMOTE_USR_REMOVE, HIDC_REMOTE_USR_REMOVE,
|
|
IDC_REMOTE_ASSISTANCE_ADVANCED, HIDC_RA_ADVANCED,
|
|
IDC_ENABLERA, HIDC_RA_ENABLE,
|
|
IDC_REMOTE_UPLINK, NO_HELP,
|
|
IDC_REMOTE_GPLINK_APPSERVER, NO_HELP,
|
|
IDC_REMOTE_SCLINK_APPSERVER, NO_HELP,
|
|
IDC_OFFLINE_FILES, NO_HELP,
|
|
IDC_REMOTE_COMPNAME, NO_HELP,
|
|
IDC_REMOTE_HELP, NO_HELP,
|
|
IDC_REMOTE_SELECT_USERS, NO_HELP,
|
|
IDC_DEFAULT1, NO_HELP,
|
|
IDC_DEFAULT2, NO_HELP,
|
|
IDC_DEFAULT3, NO_HELP,
|
|
IDC_DEFAULT4, NO_HELP,
|
|
IDC_DEFAULT5, NO_HELP,
|
|
0, 0
|
|
};
|
|
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::CRemotePage()
|
|
//
|
|
// Purpose: Initializes data members of the object
|
|
//
|
|
// Parameters: HINSTANCE hinst
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
CRemotePage::CRemotePage(
|
|
IN HINSTANCE hinst) :
|
|
m_RemoteUsersDialog(hinst)
|
|
{
|
|
m_cref = 1; //
|
|
m_bProfessional = FALSE;
|
|
m_dwPageType = PAGE_TYPE_UNKNOWN;
|
|
m_hInst = hinst;
|
|
m_bDisableChkBox = FALSE;
|
|
m_bDisableButtons = FALSE;
|
|
m_bShowAccessDeniedWarning = FALSE;
|
|
m_dwInitialState = 0;
|
|
m_hDlg = NULL;
|
|
m_TemplateId = 0;
|
|
|
|
g_uObjects++;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::~CRemotePage()
|
|
//
|
|
// Purpose: decreases the object counter
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
CRemotePage::~CRemotePage()
|
|
{
|
|
g_uObjects--;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// Interface IUnknown
|
|
///////////////////////////////
|
|
STDMETHODIMP
|
|
CRemotePage::QueryInterface(
|
|
IN REFIID riid,
|
|
OUT LPVOID *ppv)
|
|
{
|
|
if (!ppv)
|
|
return E_FAIL;
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown))
|
|
*ppv = static_cast<IShellPropSheetExt *>(this);
|
|
else if (IsEqualIID(riid, IID_IShellExtInit))
|
|
*ppv = static_cast<IShellExtInit *>(this);
|
|
else if (IsEqualIID(riid, IID_IShellPropSheetExt))
|
|
*ppv = static_cast<IShellPropSheetExt *>(this);
|
|
|
|
if (*ppv)
|
|
{
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CRemotePage::AddRef()
|
|
{
|
|
return ++m_cref;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CRemotePage::Release()
|
|
{
|
|
m_cref--;
|
|
|
|
if (!m_cref)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_cref;
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// Interface IShellExtInit
|
|
///////////////////////////////
|
|
|
|
STDMETHODIMP
|
|
CRemotePage::Initialize(
|
|
IN LPCITEMIDLIST pidlFolder,
|
|
IN LPDATAOBJECT lpdobj,
|
|
IN HKEY hkeyProgID )
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// Interface IShellPropSheetExt
|
|
///////////////////////////////
|
|
//*************************************************************
|
|
//
|
|
// AddPages()
|
|
//
|
|
// Purpose: Adds "Remote" tab to a property sheet
|
|
//
|
|
// Parameters: lpfnAddPage - function to call to add a page
|
|
// lParam - Parameter to pass to the function specified by the lpfnAddPage
|
|
|
|
//
|
|
// Return: TRUE if message was processed
|
|
// FALSE if not
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
STDMETHODIMP
|
|
CRemotePage::AddPages(
|
|
IN LPFNADDPROPSHEETPAGE lpfnAddPage,
|
|
IN LPARAM lParam )
|
|
{
|
|
|
|
if(CanShowRemotePage())
|
|
{
|
|
PROPSHEETPAGE psp;
|
|
|
|
psp.dwSize = sizeof(PROPSHEETPAGE);
|
|
psp.dwFlags = 0;
|
|
psp.hInstance = m_hInst;
|
|
psp.pszTemplate = MAKEINTRESOURCE(m_TemplateId);
|
|
psp.pfnDlgProc = RemoteDlgProc;
|
|
psp.pszTitle = NULL;
|
|
psp.lParam = (LPARAM)this;
|
|
|
|
HPROPSHEETPAGE hPage = CreatePropertySheetPage(&psp);
|
|
|
|
if(hPage && lpfnAddPage(hPage,lParam))
|
|
{
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CRemotePage::ReplacePage(
|
|
IN UINT uPageID,
|
|
IN LPFNADDPROPSHEETPAGE lpfnReplacePage,
|
|
IN LPARAM lParam )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// RemoteDlgProc()
|
|
//
|
|
// Purpose: Dialog box procedure for Remote tab
|
|
//
|
|
// Parameters: hDlg - handle to the dialog box
|
|
// uMsg - window message
|
|
// wParam - wParam
|
|
// lParam - lParam
|
|
//
|
|
// Return: TRUE if message was processed
|
|
// FALSE if not
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
INT_PTR APIENTRY
|
|
RemoteDlgProc (
|
|
HWND hDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
CRemotePage *pPage = (CRemotePage *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
PROPSHEETPAGE *ppsp=(PROPSHEETPAGE *)lParam;
|
|
pPage = (CRemotePage *)ppsp->lParam;
|
|
|
|
|
|
SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)pPage);
|
|
if(pPage)
|
|
{
|
|
pPage->AddRef();
|
|
pPage->OnInitDialog(hDlg);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
|
|
switch (((NMHDR FAR*)lParam)->code)
|
|
{
|
|
|
|
case NM_CLICK:
|
|
case NM_RETURN:
|
|
// Is for RA's help?
|
|
if (wParam == IDC_REMOTERA_HELP)
|
|
{
|
|
#if 1
|
|
#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\"")
|
|
TCHAR szCommandLine[2000];
|
|
PROCESS_INFORMATION ProcessInfo;
|
|
STARTUPINFO StartUpInfo;
|
|
|
|
TCHAR szWinDir[2048];
|
|
GetWindowsDirectory(szWinDir, 2048);
|
|
|
|
ZeroMemory((LPVOID)&StartUpInfo, sizeof(STARTUPINFO));
|
|
StartUpInfo.cb = sizeof(STARTUPINFO);
|
|
|
|
wsprintf(szCommandLine, TEXT("%s%s"), szWinDir,HELP_PATH);
|
|
CreateProcess(NULL, szCommandLine,NULL,NULL,TRUE,CREATE_NEW_PROCESS_GROUP,NULL,&szWinDir[0],&StartUpInfo,&ProcessInfo);
|
|
#else
|
|
HtmlHelp(NULL, TEXT("rassist.chm"), HH_HELP_FINDER, 0);
|
|
#endif
|
|
}
|
|
else if(pPage)
|
|
{
|
|
pPage->OnLink(wParam);
|
|
}
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
if(pPage)
|
|
{
|
|
if(pPage->OnApply())
|
|
{
|
|
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,PSNRET_NOERROR);
|
|
}
|
|
else
|
|
{
|
|
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,PSNRET_INVALID);
|
|
}
|
|
}
|
|
return TRUE;
|
|
|
|
case PSN_SETACTIVE:
|
|
if(pPage)
|
|
{
|
|
pPage->OnSetActive();
|
|
}
|
|
return TRUE;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_REMOTE_ENABLE:
|
|
if(pPage && pPage->OnRemoteEnable())
|
|
{
|
|
pPage->RemoteEnableWarning();
|
|
PropSheet_Changed(GetParent(hDlg), hDlg);
|
|
}
|
|
break;
|
|
case IDC_REMOTE_SELECT_USERS:
|
|
if(pPage)
|
|
{
|
|
pPage->OnRemoteSelectUsers();
|
|
}
|
|
break;
|
|
// Remote Assistance Dialog button.
|
|
case IDC_REMOTE_ASSISTANCE_ADVANCED:
|
|
{
|
|
BOOL bIsChanged = FALSE;
|
|
if (!g_praSetting)
|
|
{
|
|
CoCreateInstance(CLSID_RASettingProperty,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IRASettingProperty,
|
|
reinterpret_cast<void**>(&g_praSetting));
|
|
// Need to init it at the first time.
|
|
if (g_praSetting)
|
|
{
|
|
g_praSetting->Init();
|
|
}
|
|
else
|
|
{
|
|
// Not enough memory, too bad.
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
g_praSetting->ShowDialogBox(hDlg);
|
|
if (SUCCEEDED(g_praSetting->get_IsChanged(&bIsChanged)) && bIsChanged)
|
|
{
|
|
PropSheet_Changed(GetParent(hDlg), hDlg);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_ENABLERA:
|
|
{
|
|
PropSheet_Changed(GetParent(hDlg), hDlg);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_REMOTE_ASSISTANCE_ADVANCED),
|
|
IsDlgButtonChecked(hDlg, IDC_ENABLERA));
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
}
|
|
return FALSE;
|
|
|
|
case WM_DESTROY:
|
|
if(pPage)
|
|
{
|
|
pPage->Release();
|
|
}
|
|
|
|
if (g_praSetting)
|
|
{
|
|
g_praSetting->Release();
|
|
g_praSetting = NULL;
|
|
}
|
|
|
|
return FALSE; //If an application processes this message, it should return zero.
|
|
|
|
case WM_HELP:
|
|
{
|
|
LPHELPINFO phi=(LPHELPINFO)lParam;
|
|
if(phi && phi->dwContextId)
|
|
{
|
|
WinHelp(hDlg,TEXT("SYSDM.HLP"),HELP_CONTEXTPOPUP,phi->dwContextId);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_CONTEXTMENU: // right mouse click
|
|
WinHelp((HWND) wParam, TEXT("SYSDM.HLP"), HELP_CONTEXTMENU,
|
|
(DWORD_PTR)aHelpIds);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::CanShowRemotePage()
|
|
//
|
|
// Purpose: Checks Windows version;
|
|
// searches for "FDenyTSConnections" value first
|
|
// in HKLM\\Software\\Policies\\Microsoft\\Windows NT\\Terminal Services
|
|
// if not found than in
|
|
// SYSTEM\\CurrentControlSet\\Control\\Terminal Server;
|
|
// creates "Remote Desktop Users" SID,
|
|
// gets "Remote Desktop Users" group name from the SID
|
|
//
|
|
// Parameters: hInst - hInstance
|
|
// dwPageType - can be PAGE_TYPE_PTS or PAGE_TYPE_APPSERVER
|
|
//
|
|
// Return: TRUE if can show remote page
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL
|
|
CRemotePage::CanShowRemotePage()
|
|
{
|
|
|
|
BOOL fCreatePage = FALSE;
|
|
|
|
//Check Windows version
|
|
OSVERSIONINFOEX ov;
|
|
ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
if(!GetVersionEx((LPOSVERSIONINFO)&ov))
|
|
{
|
|
return FALSE;
|
|
}
|
|
if(ov.wProductType == VER_NT_WORKSTATION &&
|
|
(ov.wSuiteMask & VER_SUITE_SINGLEUSERTS ))
|
|
{
|
|
fCreatePage = TRUE;
|
|
|
|
if(ov.wSuiteMask & VER_SUITE_PERSONAL)
|
|
{
|
|
#ifdef _WIN64
|
|
// No Remote Assistance on IA64
|
|
fCreatePage = FALSE;
|
|
#else
|
|
m_dwPageType = PAGE_TYPE_PERSONAL;
|
|
m_TemplateId = IDD_REMOTE_PERSONAL;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
m_bProfessional = TRUE;
|
|
m_dwPageType = PAGE_TYPE_PTS;
|
|
m_TemplateId = IDD_REMOTE_PTS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if((ov.wProductType == VER_NT_DOMAIN_CONTROLLER || ov.wProductType == VER_NT_SERVER) &&
|
|
(ov.wSuiteMask & VER_SUITE_TERMINAL) &&
|
|
TestUserForAdmin())
|
|
{
|
|
fCreatePage = TRUE;
|
|
|
|
if(ov.wSuiteMask & VER_SUITE_SINGLEUSERTS)
|
|
{
|
|
m_dwPageType = PAGE_TYPE_PTS;
|
|
m_TemplateId = IDD_REMOTE_PTS;
|
|
}
|
|
else
|
|
{
|
|
m_dwPageType = PAGE_TYPE_APPSERVER;
|
|
m_TemplateId = IDD_REMOTE_APPSERVER;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if( !fCreatePage)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD dwType;
|
|
DWORD cbDisable;
|
|
LONG Err;
|
|
HKEY hKey;
|
|
|
|
Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEXT("Software\\Policies\\Microsoft\\Windows NT\\Terminal Services"),
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hKey);
|
|
|
|
if(Err == ERROR_SUCCESS)
|
|
{
|
|
cbDisable = sizeof(DWORD);
|
|
|
|
Err = RegQueryValueEx(hKey,
|
|
TEXT("fDenyTSConnections"),
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&m_dwInitialState,
|
|
&cbDisable);
|
|
|
|
if(Err == ERROR_SUCCESS)
|
|
{
|
|
m_bDisableChkBox = TRUE;
|
|
|
|
if(m_dwInitialState != 0)
|
|
{
|
|
m_bDisableButtons = TRUE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if(Err != ERROR_SUCCESS)
|
|
{
|
|
if(Err != ERROR_FILE_NOT_FOUND)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"),
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hKey);
|
|
|
|
if(Err == ERROR_SUCCESS)
|
|
{
|
|
cbDisable = sizeof(DWORD);
|
|
|
|
Err = RegQueryValueEx(hKey,
|
|
TEXT("fDenyTSConnections"),
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&m_dwInitialState,
|
|
&cbDisable);
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if(Err != ERROR_SUCCESS && Err != ERROR_FILE_NOT_FOUND )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//Check permissions
|
|
//on the registry
|
|
if( !m_bDisableChkBox )
|
|
{
|
|
Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"),
|
|
0,
|
|
KEY_SET_VALUE,
|
|
&hKey);
|
|
if( Err == ERROR_SUCCESS )
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
{
|
|
if( Err == ERROR_ACCESS_DENIED )
|
|
{
|
|
m_bDisableChkBox = TRUE;
|
|
m_bShowAccessDeniedWarning = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(m_dwPageType == PAGE_TYPE_PTS)
|
|
{
|
|
if(!m_bDisableButtons)
|
|
{
|
|
if(!m_RemoteUsersDialog.CanShowDialog(&m_bDisableButtons))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(m_bDisableButtons)
|
|
{
|
|
m_bShowAccessDeniedWarning = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::OnInitDialog()
|
|
//
|
|
// Purpose: initializes check box state
|
|
// creates list of "Remote Desktop Users" members
|
|
//
|
|
// Parameters: hDlg - the page handle
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemotePage::OnInitDialog(
|
|
IN HWND hDlg)
|
|
{
|
|
m_hDlg = hDlg;
|
|
|
|
/* Get Remote Assistance button value */
|
|
BOOL bRAEnable = FALSE;
|
|
int iErr;
|
|
HKEY hKey = NULL;
|
|
IRARegSetting* pRA = NULL;
|
|
CoCreateInstance(CLSID_RARegSetting,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IRARegSetting,
|
|
reinterpret_cast<void**>(&pRA));
|
|
if (pRA)
|
|
{
|
|
pRA->get_AllowGetHelpCPL(&bRAEnable);
|
|
pRA->Release();
|
|
}
|
|
|
|
CheckDlgButton(m_hDlg, IDC_ENABLERA, bRAEnable?BST_CHECKED:BST_UNCHECKED);
|
|
// check if users have permission to change this setting.
|
|
iErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"),
|
|
0,
|
|
KEY_SET_VALUE,
|
|
&hKey);
|
|
if (iErr == ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
else if (iErr == ERROR_ACCESS_DENIED)
|
|
{
|
|
bRAEnable = FALSE;
|
|
EnableWindow(GetDlgItem(m_hDlg,IDC_ENABLERA), FALSE);
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(m_hDlg,IDC_REMOTE_ASSISTANCE_ADVANCED), bRAEnable);
|
|
|
|
/***** RA done *******/
|
|
|
|
if(m_bDisableChkBox)
|
|
{
|
|
EnableWindow(GetDlgItem(m_hDlg,IDC_REMOTE_ENABLE),FALSE);
|
|
}
|
|
|
|
CheckDlgButton(m_hDlg,IDC_REMOTE_ENABLE,m_dwInitialState?BST_UNCHECKED:BST_CHECKED);
|
|
|
|
if(m_dwPageType == PAGE_TYPE_PTS)
|
|
{
|
|
|
|
if(m_bDisableButtons)
|
|
{
|
|
EnableWindow(GetDlgItem(m_hDlg,IDC_REMOTE_SELECT_USERS),FALSE);
|
|
}
|
|
|
|
//Get computer name
|
|
LPTSTR szCompName = (LPTSTR)LocalAlloc (LPTR, (MAX_PATH+1) * sizeof(TCHAR) );
|
|
DWORD dwNameSize = MAX_PATH;
|
|
|
|
if(szCompName)
|
|
{
|
|
BOOL bResult = GetComputerNameEx( ComputerNameDnsFullyQualified, szCompName, &dwNameSize );
|
|
|
|
if(!bResult && GetLastError() == ERROR_MORE_DATA)
|
|
{
|
|
LocalFree(szCompName);
|
|
szCompName = (LPTSTR) LocalAlloc (LPTR, (dwNameSize+1) * sizeof(TCHAR) );
|
|
|
|
if ( szCompName )
|
|
{
|
|
bResult = GetComputerNameEx( ComputerNameDnsFullyQualified, szCompName, &dwNameSize );
|
|
}
|
|
|
|
}
|
|
|
|
if(bResult)
|
|
{
|
|
SetDlgItemText(hDlg,IDC_REMOTE_COMPNAME,szCompName);
|
|
}
|
|
|
|
if(szCompName)
|
|
{
|
|
LocalFree(szCompName);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::OnSetActive()
|
|
//
|
|
// Purpose: When the page gets active and user does not have
|
|
// permissions to change some settings it shows
|
|
// a warning message.
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemotePage::OnSetActive()
|
|
{
|
|
TCHAR szMsg[MAX_PATH+1];
|
|
TCHAR szTitle[MAX_PATH+1];
|
|
|
|
if( m_bShowAccessDeniedWarning )
|
|
{
|
|
if(LoadString(m_hInst,IDS_REMOTE_SESSIONS,szTitle,MAX_PATH) &&
|
|
LoadString(m_hInst,IDS_WRN_NO_PERMISSIONS,szMsg,MAX_PATH))
|
|
{
|
|
MessageBox(m_hDlg,szMsg,szTitle,MB_OK|MB_ICONINFORMATION);
|
|
}
|
|
|
|
m_bShowAccessDeniedWarning = FALSE;
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::OnApply()
|
|
//
|
|
// Purpose: saves settings in the Registry
|
|
// saves "Remote Desktop Users" membership changes
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: TRUE - if changes can be applied
|
|
// FALSE - otherwise.
|
|
//
|
|
// Comments: in case of error shows message box
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
CRemotePage::OnApply()
|
|
{
|
|
CWaitCursor wait;
|
|
CMutex mutex;
|
|
|
|
DWORD dwType = REG_DWORD;
|
|
DWORD dwDisable = 0;
|
|
DWORD cbDisable = sizeof(DWORD);
|
|
LONG Err;
|
|
|
|
// Update RA setting first
|
|
IRARegSetting* pRA = NULL;
|
|
CoCreateInstance(CLSID_RARegSetting,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IRARegSetting,
|
|
reinterpret_cast<void**>(&pRA));
|
|
if (pRA)
|
|
{
|
|
pRA->put_AllowGetHelp(IsDlgButtonChecked(m_hDlg, IDC_ENABLERA)==BST_CHECKED);
|
|
pRA->Release();
|
|
}
|
|
|
|
BOOL bIsChanged = FALSE;
|
|
if (g_praSetting && SUCCEEDED(g_praSetting->get_IsChanged(&bIsChanged)) && bIsChanged)
|
|
{
|
|
g_praSetting->SetRegSetting();
|
|
}
|
|
// RA done.
|
|
|
|
if(!OnRemoteEnable())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(IsWindowEnabled(GetDlgItem(m_hDlg,IDC_REMOTE_ENABLE)))
|
|
{
|
|
|
|
if(IsDlgButtonChecked(m_hDlg,IDC_REMOTE_ENABLE) == BST_UNCHECKED)
|
|
{
|
|
dwDisable = 1;
|
|
}
|
|
|
|
|
|
if(dwDisable != m_dwInitialState)
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ILocalMachine *pLocalMachine;
|
|
|
|
hr = CoCreateInstance(CLSID_ShellLocalMachine,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ILocalMachine,
|
|
reinterpret_cast<void**>(&pLocalMachine));
|
|
if (SUCCEEDED(hr) && (pLocalMachine != NULL))
|
|
{
|
|
hr = pLocalMachine->put_isRemoteConnectionsEnabled(dwDisable == 0);
|
|
pLocalMachine->Release();
|
|
}
|
|
CoUninitialize();
|
|
}
|
|
Err = HRESULT_CODE(hr);
|
|
if (ERROR_SUCCESS == Err)
|
|
{
|
|
m_dwInitialState = dwDisable;
|
|
}
|
|
else
|
|
{
|
|
if (ERROR_NOT_SUPPORTED == Err)
|
|
{
|
|
TCHAR szContent[256], szTitle[256];
|
|
|
|
(int)LoadString(m_hInst, IDS_OTHER_USERS, szContent, sizeof(szContent) / sizeof(szContent[0]));
|
|
(int)LoadString(m_hInst, IDS_REMOTE_SESSIONS, szTitle, sizeof(szTitle) / sizeof(szTitle[0]));
|
|
MessageBox(m_hDlg, szContent, szTitle, MB_OK | MB_ICONSTOP);
|
|
}
|
|
else
|
|
{
|
|
DisplayError(m_hInst, m_hDlg, Err, IDS_ERR_SAVE_REGISTRY, IDS_REMOTE_SESSIONS);
|
|
}
|
|
CheckDlgButton(m_hDlg, IDC_REMOTE_ENABLE, m_dwInitialState ? BST_UNCHECKED : BST_CHECKED);
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::OnLink()
|
|
//
|
|
// Purpose: runs application which link points to.
|
|
//
|
|
// Parameters: WPARAM wParam - link ID
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/8/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemotePage::OnLink(
|
|
WPARAM wParam)
|
|
{
|
|
switch(wParam)
|
|
{
|
|
case IDC_REMOTE_GPLINK_APPSERVER:
|
|
ShellExecute(NULL,TEXT("open"),TEXT("gpedit.msc"),NULL,NULL,SW_SHOW);
|
|
break;
|
|
case IDC_REMOTE_SCLINK_APPSERVER:
|
|
ShellExecute(NULL,TEXT("open"),TEXT("tscc.msc"),NULL,NULL,SW_SHOW);
|
|
break;
|
|
case IDC_REMOTE_UPLINK:
|
|
ShellExecute(NULL,TEXT("open"),TEXT("control"),TEXT("userpasswords"),NULL,SW_SHOW);
|
|
break;
|
|
/*
|
|
case IDC_REMOTE_HELP:
|
|
HtmlHelp(NULL, TEXT("rdesktop.chm"), HH_HELP_FINDER, 0);
|
|
break;*/
|
|
case IDC_REMOTE_HELP:
|
|
if(m_bProfessional)
|
|
{
|
|
ShellExecute(NULL,TEXT("open"),
|
|
TEXT("hcp://services/subsite?node=TopLevelBucket_2/Working_Remotely/")
|
|
TEXT("Remote_Desktop&topic=MS-ITS:rdesktop.chm::/rdesktop_overview.htm"),NULL,NULL,SW_SHOW);
|
|
}
|
|
else
|
|
{
|
|
ShellExecute(NULL,TEXT("open"),
|
|
TEXT("hcp://services/subsite?node=Management_and_Administration_Tools/")
|
|
TEXT("Remote_Desktop_for_Administration&topic=MS-ITS:rdesktop.chm::/sag_rdesktop_topnode.htm"),NULL,NULL,SW_SHOW);
|
|
}
|
|
break;
|
|
case IDC_REMOTE_HELP_APPSERVER:
|
|
ShellExecute(NULL,TEXT("open"),
|
|
TEXT("hcp://services/subsite?node=Management_and_Administration_Tools/")
|
|
TEXT("Terminal_Server&topic=MS-ITS:termsrv.chm::/sag_termsrv_topnode.htm"),NULL,NULL,SW_SHOW);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::OnRemoteEnable()
|
|
//
|
|
// Purpose: If user tries to allow remote connections and
|
|
// "Offline Files" is enabled it shows
|
|
// "Disable Offline Files" dialog and unchecks
|
|
// "Remote Connections" checkbox.
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: TRUE - if the check box state was changed.
|
|
// FALSE - otherwise
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/8/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
|
|
typedef BOOL (WINAPI * PCHECKFN)();
|
|
|
|
BOOL
|
|
CRemotePage::OnRemoteEnable()
|
|
{
|
|
//First check if multiple connections are allowed
|
|
DWORD dwAllowMultipleTSSessions = 0;
|
|
DWORD dwType;
|
|
DWORD cbSize;
|
|
LONG Err;
|
|
HKEY hKey;
|
|
BOOL bResult = TRUE;
|
|
|
|
//Fast User Switching / Remote Connections and Offline Files should work together fine.
|
|
//when Brian Aust makes his changes to offline files.
|
|
//therefore we should not restrict remote connections in any case on Professional Machines.
|
|
//on server machine however we conntinue to disallow remote connections if Offline files are on.
|
|
if(m_bProfessional)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
//allow user to uncheck the checkbox
|
|
if(IsDlgButtonChecked(m_hDlg,IDC_REMOTE_ENABLE) == BST_UNCHECKED )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
//check if multiple sessions is allowed.
|
|
Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"),
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hKey);
|
|
|
|
if(Err == ERROR_SUCCESS)
|
|
{
|
|
cbSize = sizeof(DWORD);
|
|
|
|
Err = RegQueryValueEx(hKey,
|
|
TEXT("AllowMultipleTSSessions"),
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwAllowMultipleTSSessions,
|
|
&cbSize);
|
|
|
|
if(Err == ERROR_SUCCESS && dwAllowMultipleTSSessions)
|
|
{
|
|
//multiple sessions is allowed.
|
|
//check if CSC (Offline Files) is enabled
|
|
HMODULE hLib = LoadLibrary(TEXT("cscdll.dll"));
|
|
if(hLib)
|
|
{
|
|
PCHECKFN pfnCSCIsCSCEnabled = (PCHECKFN)GetProcAddress(hLib,"CSCIsCSCEnabled");
|
|
|
|
if(pfnCSCIsCSCEnabled && pfnCSCIsCSCEnabled())
|
|
{
|
|
//Offline Files is enabled
|
|
//uncheck the checkbox; show the dialog
|
|
COfflineFilesDialog Dlg(m_hInst);
|
|
|
|
CheckDlgButton(m_hDlg,IDC_REMOTE_ENABLE,BST_UNCHECKED);
|
|
Dlg.DoDialog(m_hDlg);
|
|
|
|
bResult = FALSE;
|
|
}
|
|
}
|
|
|
|
FreeLibrary(hLib);
|
|
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::OnRemoteSelectUsers()
|
|
//
|
|
// Purpose: Creates "Remote Desktop Users" dialog.
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemotePage::OnRemoteSelectUsers()
|
|
{
|
|
m_RemoteUsersDialog.DoDialog(m_hDlg);
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemotePage::RemoteEnableWarning()
|
|
//
|
|
// Purpose: Displays a message box about empty passwords
|
|
// firewalls and other stuff that can prevent
|
|
// remote sessions from working properly.
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/28/01 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemotePage::RemoteEnableWarning()
|
|
{
|
|
if(IsDlgButtonChecked(m_hDlg,IDC_REMOTE_ENABLE) == BST_CHECKED )
|
|
{
|
|
//
|
|
//Now warn admin about empty passwords.
|
|
//Empty passwords are not allowed with
|
|
//RemoteInteractive logon.
|
|
//
|
|
//Allocate a buffer for the string 1000 chars should be enough
|
|
//
|
|
TCHAR szTitle[MAX_PATH+1];
|
|
DWORD cMsg = 1000;
|
|
LPTSTR szMsg = (LPTSTR) LocalAlloc(LPTR,(cMsg+1)*sizeof(TCHAR));
|
|
|
|
if(szMsg)
|
|
{
|
|
if(LoadString(m_hInst,IDS_WRN_EMPTY_PASSWORD,szMsg,cMsg) &&
|
|
LoadString(m_hInst,IDS_REMOTE_SESSIONS,szTitle,MAX_PATH))
|
|
{
|
|
MessageBox(m_hDlg,szMsg,szTitle,
|
|
MB_OK | MB_ICONINFORMATION);
|
|
}
|
|
LocalFree(szMsg);
|
|
}
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// DisplayError()
|
|
//
|
|
// Purpose: shows message box with error description
|
|
//
|
|
// Parameters: ErrID - error code
|
|
// MsgID - ID of the first part of error messsage in the string table
|
|
// TitleID - ID of the title in the string table
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
DisplayError(
|
|
IN HINSTANCE hInst,
|
|
IN HWND hDlg,
|
|
IN UINT ErrID,
|
|
IN UINT MsgID,
|
|
IN UINT TitleID,
|
|
...)
|
|
{
|
|
TCHAR szTemplate[MAX_PATH+1];
|
|
TCHAR szErr[MAX_PATH+1];
|
|
|
|
if(!LoadString(hInst,MsgID,szTemplate,MAX_PATH))
|
|
{
|
|
return;
|
|
}
|
|
|
|
va_list arglist;
|
|
va_start(arglist, TitleID);
|
|
wvsprintf(szErr,szTemplate,arglist);
|
|
va_end(arglist);
|
|
|
|
TCHAR szTitle[MAX_PATH+1];
|
|
|
|
if(!LoadString(hInst,TitleID,szTitle,MAX_PATH))
|
|
{
|
|
return;
|
|
}
|
|
|
|
LPTSTR szDescr;
|
|
|
|
//load module with network error messages
|
|
HMODULE hNetErrModule=LoadLibraryEx(TEXT("netmsg.dll"),NULL,
|
|
LOAD_LIBRARY_AS_DATAFILE|DONT_RESOLVE_DLL_REFERENCES);
|
|
|
|
DWORD dwFlags;
|
|
|
|
if(hNetErrModule)
|
|
{
|
|
dwFlags=FORMAT_MESSAGE_FROM_SYSTEM|
|
|
FORMAT_MESSAGE_FROM_HMODULE|
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS;
|
|
}
|
|
else
|
|
{
|
|
dwFlags=FORMAT_MESSAGE_FROM_SYSTEM|
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS;
|
|
}
|
|
|
|
if(FormatMessage(dwFlags,
|
|
hNetErrModule,
|
|
ErrID,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPTSTR)&szDescr,
|
|
0,
|
|
NULL))
|
|
{
|
|
LPTSTR szErrMessage=(LPTSTR)LocalAlloc(LPTR,
|
|
(lstrlen(szErr)+lstrlen(szDescr)+3)*sizeof(TCHAR));
|
|
if(szErrMessage)
|
|
{
|
|
wsprintf(szErrMessage,TEXT("%s\n\n%s"),szErr,szDescr);
|
|
MessageBox(hDlg,szErrMessage,szTitle,MB_OK | MB_ICONSTOP);
|
|
LocalFree(szErrMessage);
|
|
}
|
|
LocalFree(szDescr);
|
|
}
|
|
else
|
|
{
|
|
MessageBox(hDlg,szErr,szTitle,MB_OK | MB_ICONSTOP);
|
|
}
|
|
|
|
if(hNetErrModule)
|
|
{
|
|
FreeLibrary(hNetErrModule);
|
|
}
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// getGroupMembershipPickerSettings()
|
|
//
|
|
// Purpose: prepares DSOP_SCOPE_INIT_INFO
|
|
//
|
|
// Parameters: OUT DSOP_SCOPE_INIT_INFO*& infos,
|
|
// OUT ULONG& infoCount
|
|
//
|
|
// Return: FALSE if cannot allocate memory
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
getGroupMembershipPickerSettings(
|
|
OUT DSOP_SCOPE_INIT_INFO*& infos,
|
|
OUT ULONG& infoCount)
|
|
{
|
|
|
|
|
|
static const int INFO_COUNT = 5;
|
|
infos = new DSOP_SCOPE_INIT_INFO[INFO_COUNT];
|
|
if(infos == NULL)
|
|
{
|
|
infoCount = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
infoCount = INFO_COUNT;
|
|
memset(infos, 0, sizeof(DSOP_SCOPE_INIT_INFO) * INFO_COUNT);
|
|
|
|
int scope = 0;
|
|
|
|
infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
|
|
infos[scope].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
|
|
infos[scope].flScope =
|
|
DSOP_SCOPE_FLAG_STARTING_SCOPE
|
|
| DSOP_SCOPE_FLAG_WANT_DOWNLEVEL_BUILTIN_PATH;
|
|
// this is implied for machine only scope
|
|
/* | DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT */
|
|
|
|
// allow only local users from the machine scope
|
|
|
|
infos[scope].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
|
|
infos[scope].FilterFlags.flDownlevel =
|
|
DSOP_DOWNLEVEL_FILTER_USERS;
|
|
// | DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS;
|
|
|
|
// for the domain this machine is joined to (native and mixed mode).
|
|
|
|
scope++;
|
|
infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
|
|
infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
|
|
infos[scope].flType =
|
|
DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
|
|
| DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
|
|
|
|
infos[scope].FilterFlags.Uplevel.flNativeModeOnly =
|
|
DSOP_FILTER_GLOBAL_GROUPS_SE
|
|
| DSOP_FILTER_UNIVERSAL_GROUPS_SE
|
|
//| DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE
|
|
| DSOP_FILTER_USERS;
|
|
|
|
// here, we allow only domain global groups and domain users. While
|
|
// it is possible to add a domain local group to a machine local group,
|
|
// I'm told such an operation is not really useful from an administraion
|
|
// perspective.
|
|
|
|
infos[scope].FilterFlags.Uplevel.flMixedModeOnly =
|
|
DSOP_FILTER_GLOBAL_GROUPS_SE
|
|
| DSOP_FILTER_USERS;
|
|
|
|
// same comment above re: domain local groups applies here too.
|
|
|
|
infos[scope].FilterFlags.flDownlevel =
|
|
DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS
|
|
| DSOP_DOWNLEVEL_FILTER_USERS;
|
|
|
|
// for domains in the same tree (native and mixed mode)
|
|
|
|
scope++;
|
|
infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
|
|
infos[scope].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
|
|
infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
|
|
|
|
infos[scope].FilterFlags.Uplevel.flNativeModeOnly =
|
|
DSOP_FILTER_GLOBAL_GROUPS_SE
|
|
| DSOP_FILTER_UNIVERSAL_GROUPS_SE
|
|
| DSOP_FILTER_USERS;
|
|
|
|
// above domain local group comment applies here, too.
|
|
|
|
infos[scope].FilterFlags.Uplevel.flMixedModeOnly =
|
|
DSOP_FILTER_GLOBAL_GROUPS_SE
|
|
| DSOP_FILTER_USERS;
|
|
|
|
// for external trusted domains
|
|
|
|
scope++;
|
|
infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
|
|
infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
|
|
infos[scope].flType =
|
|
DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
|
|
| DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
|
|
|
|
infos[scope].FilterFlags.Uplevel.flNativeModeOnly =
|
|
DSOP_FILTER_GLOBAL_GROUPS_SE
|
|
| DSOP_FILTER_UNIVERSAL_GROUPS_SE
|
|
| DSOP_FILTER_USERS;
|
|
|
|
infos[scope].FilterFlags.Uplevel.flMixedModeOnly =
|
|
DSOP_FILTER_GLOBAL_GROUPS_SE
|
|
| DSOP_FILTER_USERS;
|
|
|
|
infos[scope].FilterFlags.flDownlevel =
|
|
DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS
|
|
| DSOP_DOWNLEVEL_FILTER_USERS;
|
|
|
|
// for the global catalog
|
|
|
|
scope++;
|
|
infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
|
|
infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
|
|
infos[scope].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
|
|
|
|
// only native mode applies to gc scope.
|
|
|
|
infos[scope].FilterFlags.Uplevel.flNativeModeOnly =
|
|
DSOP_FILTER_GLOBAL_GROUPS_SE
|
|
| DSOP_FILTER_UNIVERSAL_GROUPS_SE
|
|
| DSOP_FILTER_USERS;
|
|
|
|
// SPB:252126 the workgroup scope doesn't apply in this case
|
|
// // for when the machine is not joined to a domain
|
|
// scope++;
|
|
// infos[scope].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
|
|
// infos[scope].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
|
|
// infos[scope].flType = DSOP_SCOPE_TYPE_WORKGROUP;
|
|
//
|
|
// infos[scope].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
|
|
// infos[scope].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
|
|
|
|
_ASSERT(scope == INFO_COUNT - 1);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// VariantToSid()
|
|
//
|
|
// Purpose: Converts a VARIANT containing a safe array
|
|
// of bytes to a SID
|
|
//
|
|
// Parameters: IN VARIANT* var,
|
|
// OUT PSID *ppSid
|
|
//
|
|
// Return:
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/13/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
HRESULT
|
|
VariantToSid(
|
|
IN VARIANT* var,
|
|
OUT PSID *ppSid)
|
|
{
|
|
_ASSERT(var);
|
|
_ASSERT(V_VT(var) == (VT_ARRAY | VT_UI1));
|
|
|
|
HRESULT hr = S_OK;
|
|
SAFEARRAY* psa = V_ARRAY(var);
|
|
|
|
do
|
|
{
|
|
_ASSERT(psa);
|
|
if (!psa)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
|
|
if (SafeArrayGetDim(psa) != 1)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
|
|
if (SafeArrayGetElemsize(psa) != 1)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
|
|
PSID sid = 0;
|
|
hr = SafeArrayAccessData(psa, reinterpret_cast<void**>(&sid));
|
|
if(FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (!IsValidSid(sid))
|
|
{
|
|
SafeArrayUnaccessData(psa);
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
|
|
*ppSid = (PSID) new BYTE[GetLengthSid(sid)];
|
|
|
|
if(!(*ppSid))
|
|
{
|
|
SafeArrayUnaccessData(psa);
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
CopySid(GetLengthSid(sid),*ppSid,sid);
|
|
SafeArrayUnaccessData(psa);
|
|
|
|
} while (0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* TestUserForAdmin - Hydrix helper function
|
|
*
|
|
* Returns whether the current thread is running under admin
|
|
* security.
|
|
*
|
|
* ENTRY:
|
|
* NONE
|
|
*
|
|
* EXIT:
|
|
* TRUE/FALSE - whether user is specified admin
|
|
*
|
|
****************************************************************************/
|
|
|
|
BOOL
|
|
TestUserForAdmin()
|
|
{
|
|
BOOL IsMember, IsAnAdmin;
|
|
SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
|
|
PSID AdminSid;
|
|
|
|
|
|
if (!AllocateAndInitializeSid(&SystemSidAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&AdminSid))
|
|
{
|
|
IsAnAdmin = FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (!CheckTokenMembership( NULL,
|
|
AdminSid,
|
|
&IsMember))
|
|
{
|
|
FreeSid(AdminSid);
|
|
IsAnAdmin = FALSE;
|
|
}
|
|
else
|
|
{
|
|
FreeSid(AdminSid);
|
|
IsAnAdmin = IsMember;
|
|
}
|
|
}
|
|
|
|
return IsAnAdmin;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// OfflineFilesDlgProc()
|
|
//
|
|
// Purpose: Dialog box procedure for "Disable Offline Files" dialog
|
|
//
|
|
// Parameters: hDlg - handle to the dialog box
|
|
// uMsg - window message
|
|
// wParam - wParam
|
|
// lParam - lParam (if uMsg is WM_INITDIALOG - this is a pointer to
|
|
// object of COfflineFilesDialog class)
|
|
//
|
|
// Return: TRUE if message was processed
|
|
// FALSE if not
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/9/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
INT_PTR APIENTRY
|
|
OfflineFilesDlgProc (
|
|
HWND hDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
|
|
COfflineFilesDialog *pDlg = (COfflineFilesDialog *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
pDlg=(COfflineFilesDialog *)lParam;
|
|
SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)pDlg);
|
|
if(pDlg)
|
|
{
|
|
pDlg->OnInitDialog(hDlg);
|
|
}
|
|
}
|
|
break;
|
|
case WM_NOTIFY:
|
|
|
|
switch (((NMHDR FAR*)lParam)->code)
|
|
{
|
|
|
|
case NM_CLICK:
|
|
case NM_RETURN:
|
|
if(pDlg)
|
|
{
|
|
pDlg->OnLink(wParam);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
EndDialog(hDlg,0);
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
// class COfflineFilesDialog
|
|
//*************************************************************
|
|
|
|
//*************************************************************
|
|
//
|
|
// COfflineFilesDialog::COfflineFilesDialog()
|
|
//
|
|
// Purpose: Constructor
|
|
// Parameters: HINSTANCE hInst
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/8/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
COfflineFilesDialog::COfflineFilesDialog(
|
|
IN HINSTANCE hInst)
|
|
: m_hInst(hInst),m_hDlg(NULL)
|
|
{
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// COfflineFilesDialog::DoDialog()
|
|
//
|
|
// Purpose: Creates "Disable Offline Files" dialog
|
|
//
|
|
// Parameters: HWND hwndParent
|
|
//
|
|
// Return:
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/8/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
INT_PTR
|
|
COfflineFilesDialog::DoDialog(
|
|
IN HWND hwndParent)
|
|
{
|
|
return DialogBoxParam(
|
|
m_hInst,
|
|
MAKEINTRESOURCE(IDD_DISABLE_OFFLINE_FILES),
|
|
hwndParent,
|
|
OfflineFilesDlgProc,
|
|
(LPARAM) this);
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// COfflineFilesDialog::OnInitDialog()
|
|
//
|
|
// Purpose: Initializes m_hDlg variable
|
|
//
|
|
// Parameters: HWND hDlg
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/8/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
COfflineFilesDialog::OnInitDialog(
|
|
IN HWND hDlg)
|
|
{
|
|
m_hDlg = hDlg;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// COfflineFilesDialog::OnLink()
|
|
//
|
|
// Purpose: If ID of the link is IDC_OFFLINE_FILES
|
|
// it shows "Offline Files" property page.
|
|
//
|
|
// Parameters: WPARAM wParam - ID of the link.
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/9/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
|
|
typedef DWORD (WINAPI * PFNCSCPROP)(HWND);
|
|
|
|
void
|
|
COfflineFilesDialog::OnLink(
|
|
IN WPARAM wParam)
|
|
{
|
|
if(wParam == IDC_OFFLINE_FILES)
|
|
{
|
|
HINSTANCE hLib = LoadLibrary(TEXT("cscui.dll"));
|
|
if (hLib)
|
|
{
|
|
PFNCSCPROP pfnCSCUIOptionsPropertySheet =
|
|
(PFNCSCPROP)GetProcAddress(hLib, "CSCUIOptionsPropertySheet");
|
|
|
|
if (pfnCSCUIOptionsPropertySheet)
|
|
{
|
|
pfnCSCUIOptionsPropertySheet(m_hDlg);
|
|
}
|
|
|
|
FreeLibrary(hLib);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//*************************************************************
|
|
// class CRemoteUsersDialog
|
|
//*************************************************************
|
|
//*************************************************************
|
|
//
|
|
// RemoteUsersDlgProc()
|
|
//
|
|
// Purpose: Dialog box procedure for "Remote Desktop Users" dialog
|
|
//
|
|
// Parameters: hDlg - handle to the dialog box
|
|
// uMsg - window message
|
|
// wParam - wParam
|
|
// lParam - lParam (if uMsg is WM_INITDIALOG - this is a pointer to
|
|
// object of CRemoteUsersDialog class)
|
|
//
|
|
// Return: TRUE if message was processed
|
|
// FALSE if not
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/22/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
INT_PTR APIENTRY
|
|
RemoteUsersDlgProc (
|
|
HWND hDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
|
|
CRemoteUsersDialog *pDlg = (CRemoteUsersDialog *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
pDlg=(CRemoteUsersDialog *)lParam;
|
|
SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)pDlg);
|
|
if(pDlg)
|
|
{
|
|
pDlg->OnInitDialog(hDlg);
|
|
}
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_NOTIFY:
|
|
|
|
switch (((NMHDR FAR*)lParam)->code)
|
|
{
|
|
|
|
case NM_CLICK:
|
|
case NM_RETURN:
|
|
if(pDlg)
|
|
{
|
|
pDlg->OnLink(wParam);
|
|
}
|
|
return TRUE;
|
|
|
|
case LVN_ITEMCHANGED:
|
|
if(pDlg)
|
|
{
|
|
pDlg->OnItemChanged(lParam);
|
|
}
|
|
return TRUE;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
if(pDlg)
|
|
{
|
|
pDlg->OnOk();
|
|
}
|
|
EndDialog(hDlg,0);
|
|
break;
|
|
case IDCANCEL:
|
|
EndDialog(hDlg,0);
|
|
break;
|
|
case IDC_REMOTE_USR_ADD:
|
|
if(pDlg)
|
|
{
|
|
pDlg->AddUsers();
|
|
}
|
|
break;
|
|
case IDC_REMOTE_USR_REMOVE:
|
|
if(pDlg)
|
|
{
|
|
pDlg->RemoveUsers();
|
|
}
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
SetWindowLong(hDlg,DWLP_MSGRESULT,0);
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
if(pDlg)
|
|
{
|
|
pDlg->OnDestroyWindow();
|
|
}
|
|
SetWindowLong(hDlg,DWLP_MSGRESULT,0);
|
|
return TRUE;
|
|
|
|
case WM_HELP:
|
|
{
|
|
LPHELPINFO phi=(LPHELPINFO)lParam;
|
|
if(phi && phi->dwContextId)
|
|
{
|
|
WinHelp(hDlg,TEXT("SYSDM.HLP"),HELP_CONTEXTPOPUP,phi->dwContextId);
|
|
SetWindowLong(hDlg,DWLP_MSGRESULT,TRUE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_CONTEXTMENU: // right mouse click
|
|
WinHelp((HWND) wParam, TEXT("SYSDM.HLP"), HELP_CONTEXTMENU,
|
|
(DWORD_PTR)aHelpIds);
|
|
return TRUE;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::CRemoteUsersDialog()
|
|
//
|
|
// Purpose: Constructor
|
|
// Parameters: HINSTANCE hInst
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/22/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
CRemoteUsersDialog::CRemoteUsersDialog(
|
|
IN HINSTANCE hInst)
|
|
: m_hInst(hInst),m_hDlg(NULL),m_bCanShowDialog(FALSE)
|
|
{
|
|
m_szRemoteGroupName[0] = 0;
|
|
m_szLocalCompName[0] = 0;
|
|
m_hList = NULL;
|
|
m_iLocUser = m_iGlobUser = m_iLocGroup = m_iGlobGroup = m_iUnknown = 0;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::DoDialog()
|
|
//
|
|
// Purpose: Creates "Remote Desktop Users" dialog
|
|
//
|
|
// Parameters: HWND hwndParent
|
|
//
|
|
// Return:
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/22/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
INT_PTR
|
|
CRemoteUsersDialog::DoDialog(
|
|
IN HWND hwndParent)
|
|
{
|
|
if(!m_bCanShowDialog)
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
return DialogBoxParam(
|
|
m_hInst,
|
|
MAKEINTRESOURCE(IDD_REMOTE_DESKTOP_USERS),
|
|
hwndParent,
|
|
RemoteUsersDlgProc,
|
|
(LPARAM) this);
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::CanShowDialog()
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Parameters: IN OUT LPBOOL pbAccessDenied - set to TRUE if
|
|
// NetLocalGroupAddMembers returns ACCESS_DENIED.
|
|
//
|
|
// Return:
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
CRemoteUsersDialog::CanShowDialog(
|
|
IN OUT LPBOOL pbAccessDenied)
|
|
{
|
|
*pbAccessDenied = FALSE;
|
|
|
|
//get name of the "Remote Desktop Users" group
|
|
//(it can depend on the language used)
|
|
|
|
//first create SID
|
|
SID_IDENTIFIER_AUTHORITY NtSidAuthority = SECURITY_NT_AUTHORITY;
|
|
PSID pSid = NULL;
|
|
if( !AllocateAndInitializeSid(
|
|
&NtSidAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&pSid
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//Lookup name
|
|
m_szRemoteGroupName[0] = 0;
|
|
|
|
DWORD cRemoteGroupName = MAX_PATH;
|
|
WCHAR szDomainName[MAX_PATH+1];
|
|
DWORD cDomainName = MAX_PATH;
|
|
SID_NAME_USE eUse;
|
|
if(!LookupAccountSidW(NULL,pSid,
|
|
m_szRemoteGroupName,&cRemoteGroupName,
|
|
szDomainName,&cDomainName,
|
|
&eUse))
|
|
{
|
|
FreeSid(pSid);
|
|
return FALSE;
|
|
}
|
|
FreeSid(pSid);
|
|
|
|
//on the group
|
|
//we trying to add 0 members to the group to see if it returns
|
|
//ACCESS DENIED
|
|
NET_API_STATUS Result= NetLocalGroupAddMembers(NULL,m_szRemoteGroupName,0,NULL,0);
|
|
|
|
if(Result == ERROR_ACCESS_DENIED)
|
|
{
|
|
*pbAccessDenied = TRUE;
|
|
}
|
|
|
|
m_bCanShowDialog = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::OnInitDialog()
|
|
//
|
|
// Purpose: Initializes m_hDlg variable
|
|
//
|
|
// Parameters: HWND hDlg
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/8/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::OnInitDialog(
|
|
IN HWND hDlg)
|
|
{
|
|
m_hDlg = hDlg;
|
|
|
|
m_szLocalCompName[0] = 0;
|
|
DWORD cCompName = MAX_PATH;
|
|
GetComputerNameW(m_szLocalCompName,&cCompName);
|
|
|
|
//fill list of Remote Desktop Users
|
|
m_hList = GetDlgItem(m_hDlg,IDC_REMOTE_USR_LIST);
|
|
|
|
if(m_hList)
|
|
{
|
|
|
|
//create image list
|
|
HIMAGELIST hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
|
|
GetSystemMetrics(SM_CYSMICON), ILC_MASK , 5, 1);
|
|
if(hImageList)
|
|
{
|
|
HICON hIcon;
|
|
|
|
hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_UNKNOWN), IMAGE_ICON,
|
|
16, 16, 0);
|
|
if (hIcon)
|
|
{
|
|
m_iUnknown = ImageList_AddIcon(hImageList, hIcon);
|
|
DestroyIcon(hIcon);
|
|
}
|
|
|
|
hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_LOC_USER), IMAGE_ICON,
|
|
16, 16, 0);
|
|
if (hIcon)
|
|
{
|
|
m_iLocUser = ImageList_AddIcon(hImageList, hIcon);
|
|
DestroyIcon(hIcon);
|
|
}
|
|
|
|
hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_GLOB_USER), IMAGE_ICON,
|
|
16, 16, 0);
|
|
if (hIcon)
|
|
{
|
|
m_iGlobUser = ImageList_AddIcon(hImageList, hIcon);
|
|
DestroyIcon(hIcon);
|
|
}
|
|
|
|
hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_LOC_GROUP), IMAGE_ICON,
|
|
16, 16, 0);
|
|
if (hIcon)
|
|
{
|
|
m_iLocGroup = ImageList_AddIcon(hImageList, hIcon);
|
|
DestroyIcon(hIcon);
|
|
}
|
|
|
|
hIcon = (HICON) LoadImage(m_hInst, MAKEINTRESOURCE(IDI_GLOB_GROUP), IMAGE_ICON,
|
|
16, 16, 0);
|
|
if (hIcon)
|
|
{
|
|
m_iGlobGroup = ImageList_AddIcon(hImageList, hIcon);
|
|
DestroyIcon(hIcon);
|
|
}
|
|
|
|
ListView_SetImageList(m_hList,hImageList,LVSIL_SMALL);
|
|
}
|
|
|
|
ReloadList();
|
|
}
|
|
|
|
//If current user already has remote logon access,
|
|
//remind it to him by showing corresponding text in the dialog.
|
|
InitAccessMessage();
|
|
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::OnLink()
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Parameters: WPARAM wParam - ID of the link.
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 5/9/00 a-skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::OnLink(
|
|
IN WPARAM wParam)
|
|
{
|
|
switch(wParam)
|
|
{
|
|
case IDC_REMOTE_UPLINK:
|
|
ShellExecute(NULL,TEXT("open"),TEXT("control"),TEXT("userpasswords"),NULL,SW_SHOW);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::OnOk()
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: TRUE if success
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
CRemoteUsersDialog::OnOk()
|
|
{
|
|
if(m_hList)
|
|
{
|
|
//Apply members
|
|
LOCALGROUP_MEMBERS_INFO_0 *plmi0 = NULL;
|
|
DWORD entriesread;
|
|
DWORD totalentries;
|
|
NET_API_STATUS Result;
|
|
Result = NetLocalGroupGetMembers(NULL,m_szRemoteGroupName,0,(LPBYTE *)&plmi0,
|
|
MAX_PREFERRED_LENGTH,&entriesread,&totalentries,NULL);
|
|
|
|
if(Result == NERR_Success)
|
|
{
|
|
|
|
int j;
|
|
LOCALGROUP_MEMBERS_INFO_0 lmi0;
|
|
|
|
LVITEM lvi;
|
|
lvi.iSubItem = 0;
|
|
lvi.mask = LVIF_PARAM ;
|
|
|
|
int iItems=ListView_GetItemCount(m_hList);
|
|
|
|
BOOL *pbDoNotAdd = new BOOL[iItems];
|
|
|
|
if(!pbDoNotAdd)
|
|
{
|
|
if(plmi0)
|
|
{
|
|
NetApiBufferFree(plmi0);
|
|
}
|
|
//not enough memory - too bad
|
|
return TRUE;
|
|
}
|
|
|
|
ZeroMemory(pbDoNotAdd,iItems*sizeof(BOOL));
|
|
|
|
for(DWORD i=0;i<entriesread;i++)
|
|
{
|
|
j = FindItemBySid(plmi0[i].lgrmi0_sid);
|
|
|
|
//SID was not found in the list - delete member
|
|
if(j == -1)
|
|
{
|
|
lmi0.lgrmi0_sid = plmi0[i].lgrmi0_sid;
|
|
|
|
Result = NetLocalGroupDelMembers(NULL,m_szRemoteGroupName,0,(LPBYTE)&lmi0,1);
|
|
|
|
if(Result !=NERR_Success)
|
|
{
|
|
delete pbDoNotAdd;
|
|
NetApiBufferFree(plmi0);
|
|
DisplayError(m_hInst, m_hDlg, Result, IDS_ERR_SAVE_MEMBERS, IDS_REMOTE_SESSIONS,
|
|
m_szRemoteGroupName, m_szLocalCompName);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pbDoNotAdd[j] = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
//Add the rest of members to the group
|
|
for(j=0;j<iItems;j++)
|
|
{
|
|
if(!pbDoNotAdd[j])
|
|
{
|
|
lvi.iItem = j;
|
|
ListView_GetItem( m_hList, &lvi );
|
|
lmi0.lgrmi0_sid = (PSID) lvi.lParam;
|
|
|
|
Result = NetLocalGroupAddMembers(NULL,m_szRemoteGroupName,0,(LPBYTE)&lmi0,1);
|
|
|
|
if(Result !=NERR_Success)
|
|
{
|
|
delete pbDoNotAdd;
|
|
NetApiBufferFree(plmi0);
|
|
DisplayError(m_hInst, m_hDlg, Result, IDS_ERR_SAVE_MEMBERS, IDS_REMOTE_SESSIONS,
|
|
m_szRemoteGroupName, m_szLocalCompName);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete pbDoNotAdd;
|
|
NetApiBufferFree(plmi0);
|
|
}
|
|
else
|
|
{
|
|
DisplayError(m_hInst, m_hDlg, Result, IDS_ERR_SAVE_MEMBERS, IDS_REMOTE_SESSIONS,
|
|
m_szRemoteGroupName, m_szLocalCompName);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::OnItemChanged()
|
|
//
|
|
// Purpose: Enables or disables "Remove" button.
|
|
//
|
|
// Parameters: lParam -
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments: in case of error shows message box
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::OnItemChanged(
|
|
LPARAM lParam)
|
|
{
|
|
NMLISTVIEW* lv = reinterpret_cast<NMLISTVIEW*>(lParam);
|
|
if (lv->uChanged & LVIF_STATE)
|
|
{
|
|
// a list item changed state
|
|
BOOL selected = ListView_GetSelectedCount(m_hList) > 0;
|
|
|
|
EnableWindow(GetDlgItem(m_hDlg, IDC_REMOTE_USR_REMOVE), selected);
|
|
|
|
//If we disabled IDC_REMOTE_USR_REMOVE button while it had focus
|
|
//all property page loses focus so "Tab" key does not
|
|
//work anymore. We need to restore focus.
|
|
if(!GetFocus())
|
|
{
|
|
SetFocus(m_hDlg);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::OnDestroyWindow()
|
|
//
|
|
// Purpose: Frees memory allocated by member's SIDs
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::OnDestroyWindow()
|
|
{
|
|
if(m_hList)
|
|
{
|
|
int iItems=ListView_GetItemCount(m_hList);
|
|
|
|
LVITEM lvi;
|
|
lvi.iSubItem = 0;
|
|
lvi.mask = LVIF_PARAM;
|
|
|
|
while(iItems)
|
|
{
|
|
lvi.iItem = 0;
|
|
ListView_GetItem( m_hList, &lvi );
|
|
//delete item
|
|
ListView_DeleteItem(m_hList, 0);
|
|
if(lvi.lParam)
|
|
{
|
|
delete (LPVOID)lvi.lParam;
|
|
}
|
|
iItems--; //decrease item count
|
|
}
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::AddUsers()
|
|
//
|
|
// Purpose: adds users to the list
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::AddUsers()
|
|
{
|
|
HRESULT hr = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
IDsObjectPicker *pDsObjectPicker = NULL;
|
|
|
|
hr = CoCreateInstance(CLSID_DsObjectPicker,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDsObjectPicker,
|
|
(void **) &pDsObjectPicker);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
|
|
DSOP_INIT_INFO initInfo;
|
|
memset(&initInfo, 0, sizeof(initInfo));
|
|
|
|
initInfo.cbSize = sizeof(initInfo);
|
|
initInfo.flOptions = DSOP_FLAG_MULTISELECT;
|
|
|
|
// aliasing the computerName internal pointer here -- ok, as lifetime
|
|
// of computerName > initInfo
|
|
|
|
initInfo.pwzTargetComputer = NULL;
|
|
|
|
initInfo.cAttributesToFetch = 1;
|
|
PWSTR attrs[2] = {0, 0};
|
|
attrs[0] = L"ObjectSID";
|
|
|
|
// obtuse notation required to cast *in* const and away the static len
|
|
|
|
initInfo.apwzAttributeNames = const_cast<PCWSTR*>(&attrs[0]);
|
|
|
|
if(getGroupMembershipPickerSettings(initInfo.aDsScopeInfos, initInfo.cDsScopeInfos))
|
|
{
|
|
|
|
IDataObject* pdo = NULL;
|
|
|
|
if(SUCCEEDED(pDsObjectPicker->Initialize(&initInfo)) &&
|
|
pDsObjectPicker->InvokeDialog(m_hDlg, &pdo) == S_OK &&
|
|
pdo )
|
|
{
|
|
CWaitCursor wait;
|
|
|
|
static const UINT cf = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
|
|
|
|
FORMATETC formatetc =
|
|
{
|
|
(CLIPFORMAT)cf,
|
|
0,
|
|
DVASPECT_CONTENT,
|
|
-1,
|
|
TYMED_HGLOBAL
|
|
};
|
|
|
|
STGMEDIUM stgmedium =
|
|
{
|
|
TYMED_HGLOBAL,
|
|
0
|
|
};
|
|
|
|
if(cf && SUCCEEDED(pdo->GetData(&formatetc, &stgmedium)))
|
|
{
|
|
|
|
PVOID lockedHGlobal = GlobalLock(stgmedium.hGlobal);
|
|
|
|
DS_SELECTION_LIST* selections =
|
|
reinterpret_cast<DS_SELECTION_LIST*>(lockedHGlobal);
|
|
|
|
AddPickerItems(selections);
|
|
|
|
GlobalUnlock(stgmedium.hGlobal);
|
|
}
|
|
|
|
pdo->Release();
|
|
}
|
|
|
|
delete initInfo.aDsScopeInfos;
|
|
}
|
|
|
|
pDsObjectPicker->Release();
|
|
}
|
|
|
|
CoUninitialize();
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::RemoveUsers()
|
|
//
|
|
// Purpose: Removes users from the list
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::RemoveUsers()
|
|
{
|
|
//delete all selected items
|
|
if(m_hList)
|
|
{
|
|
|
|
int iItems=ListView_GetItemCount(m_hList);
|
|
UINT uiState=0;
|
|
int i=0;
|
|
LVITEM lvi;
|
|
lvi.iSubItem = 0;
|
|
lvi.mask = LVIF_STATE | LVIF_PARAM;
|
|
lvi.stateMask = LVIS_SELECTED;
|
|
|
|
while(i<iItems)
|
|
{
|
|
lvi.iItem = i;
|
|
ListView_GetItem( m_hList, &lvi );
|
|
if(lvi.state&LVIS_SELECTED)
|
|
{
|
|
//delete item
|
|
ListView_DeleteItem(m_hList, i);
|
|
if(lvi.lParam)
|
|
{
|
|
delete (LPVOID)lvi.lParam;
|
|
}
|
|
iItems--; //decrease item count
|
|
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
|
|
//If list is not empty, set focus on the first item.
|
|
if( ListView_GetItemCount(m_hList) )
|
|
{
|
|
ListView_SetItemState(m_hList, 0, LVIS_FOCUSED, LVIS_FOCUSED );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::IsLocal()
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Parameters: wszDomainandname - domain\user
|
|
// determines whether the user is local or not
|
|
// if local - cuts out domain name
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
CRemoteUsersDialog::IsLocal(
|
|
LPWSTR wszDomainandname)
|
|
{
|
|
LPWSTR wszTmp = wcschr(wszDomainandname,L'\\');
|
|
|
|
if(!wszTmp)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if(!_wcsnicmp(wszDomainandname, m_szLocalCompName,wcslen(m_szLocalCompName) ))
|
|
{
|
|
//get rid of useless domain name
|
|
wcscpy(wszDomainandname,wszTmp+1);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::AddPickerItems()
|
|
//
|
|
// Purpose: adds items, returned by DSObjectPicker
|
|
// to the list
|
|
//
|
|
// Parameters: IN DS_SELECTION_LIST *selections
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::AddPickerItems(
|
|
IN DS_SELECTION_LIST *selections)
|
|
{
|
|
|
|
if(!selections)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DS_SELECTION* current = &(selections->aDsSelection[0]);
|
|
|
|
if(m_hList)
|
|
{
|
|
|
|
for (ULONG i = 0; i < selections->cItems; i++, current++)
|
|
{
|
|
|
|
// extract the ObjectSID of the object (this should always be
|
|
// present)
|
|
|
|
PSID pSid;
|
|
HRESULT hr = VariantToSid(¤t->pvarFetchedAttributes[0],&pSid);
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
//This SID is not in the list
|
|
//Let's add it.
|
|
if(FindItemBySid(pSid) == -1)
|
|
{
|
|
LPWSTR szFullName = NULL;
|
|
SID_NAME_USE eUse;
|
|
|
|
LVITEM item;
|
|
ZeroMemory(&item,sizeof(item));
|
|
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
|
|
|
//put SID it into the item data
|
|
//the allocated memory will be freed in OnDestroyWindow()
|
|
item.lParam = (LPARAM)pSid;
|
|
|
|
if(LookupSid(pSid,&szFullName, &eUse))
|
|
{
|
|
item.pszText = szFullName;
|
|
}
|
|
else
|
|
{
|
|
eUse = SidTypeUnknown;
|
|
if(current->pwzName)
|
|
{
|
|
item.pszText = current->pwzName;
|
|
}
|
|
else
|
|
{
|
|
item.pszText = L"?";
|
|
}
|
|
}
|
|
|
|
switch(eUse)
|
|
{
|
|
case SidTypeUser:
|
|
item.iImage = IsLocal(szFullName) ? m_iLocUser : m_iGlobUser;
|
|
break;
|
|
case SidTypeGroup:
|
|
item.iImage = IsLocal(szFullName) ? m_iLocGroup : m_iGlobGroup;
|
|
break;
|
|
case SidTypeWellKnownGroup:
|
|
item.iImage = m_iLocGroup;
|
|
break;
|
|
|
|
default:
|
|
item.iImage = m_iUnknown;
|
|
break;
|
|
}
|
|
|
|
if(ListView_InsertItem(m_hList,&item) == -1)
|
|
{
|
|
delete pSid;
|
|
}
|
|
|
|
if(szFullName)
|
|
{
|
|
LocalFree(szFullName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Free allocated memory
|
|
delete pSid;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::FindItemBySid()
|
|
//
|
|
// Purpose: finds user with particular SID in the list
|
|
//
|
|
// Parameters: pSid - SID to find
|
|
//
|
|
// Return: item index (-1 if not found)
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
int
|
|
CRemoteUsersDialog::FindItemBySid(
|
|
IN PSID pSid)
|
|
{
|
|
if(m_hList)
|
|
{
|
|
LVITEM lvi;
|
|
lvi.iSubItem = 0;
|
|
lvi.mask = LVIF_PARAM ;
|
|
|
|
int iItems=ListView_GetItemCount(m_hList);
|
|
|
|
for(int i=0;i<iItems;i++)
|
|
{
|
|
lvi.iItem = i;
|
|
ListView_GetItem( m_hList, &lvi );
|
|
PSID pItemSid = (PSID) lvi.lParam;
|
|
if(pItemSid && EqualSid(pSid,pItemSid))
|
|
{
|
|
return i;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::ReloadList()
|
|
//
|
|
// Purpose: delete all items and then refill it with
|
|
// names of members of "Remote Desktop Users" group.
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 12/27/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::ReloadList()
|
|
{
|
|
|
|
if(m_hList)
|
|
{
|
|
CWaitCursor wait;
|
|
|
|
//first delete all items
|
|
int iItems=ListView_GetItemCount(m_hList);
|
|
|
|
LVITEM item;
|
|
item.iSubItem = 0;
|
|
item.mask = LVIF_PARAM;
|
|
|
|
while(iItems)
|
|
{
|
|
item.iItem = 0;
|
|
ListView_GetItem( m_hList, &item );
|
|
//delete item
|
|
ListView_DeleteItem(m_hList, 0);
|
|
if(item.lParam)
|
|
{
|
|
delete (LPVOID)item.lParam;
|
|
}
|
|
iItems--; //decrease item count
|
|
}
|
|
|
|
LOCALGROUP_MEMBERS_INFO_2 *plmi2;
|
|
DWORD entriesread;
|
|
DWORD totalentries;
|
|
NET_API_STATUS Result;
|
|
Result = NetLocalGroupGetMembers(NULL,m_szRemoteGroupName,2,(LPBYTE *)&plmi2,
|
|
MAX_PREFERRED_LENGTH,&entriesread,&totalentries,NULL);
|
|
if(Result == NERR_Success || Result == ERROR_MORE_DATA )
|
|
{
|
|
|
|
for(DWORD i=0;i<entriesread;i++)
|
|
{
|
|
ZeroMemory(&item,sizeof(item));
|
|
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
|
item.pszText = plmi2[i].lgrmi2_domainandname;
|
|
//create copy of the SID and put it in item data
|
|
PSID pSid = (PSID)new BYTE[GetLengthSid(plmi2[i].lgrmi2_sid)];
|
|
if(pSid)
|
|
{
|
|
CopySid(GetLengthSid(plmi2[i].lgrmi2_sid),pSid,plmi2[i].lgrmi2_sid);
|
|
item.lParam = (LPARAM)pSid;
|
|
}
|
|
switch(plmi2[i].lgrmi2_sidusage)
|
|
{
|
|
case SidTypeUser:
|
|
item.iImage = IsLocal(plmi2[i].lgrmi2_domainandname) ? m_iLocUser : m_iGlobUser;
|
|
break;
|
|
case SidTypeGroup:
|
|
item.iImage = IsLocal(plmi2[i].lgrmi2_domainandname) ? m_iLocGroup : m_iGlobGroup;
|
|
break;
|
|
case SidTypeWellKnownGroup:
|
|
item.iImage = m_iLocGroup;
|
|
break;
|
|
|
|
default:
|
|
item.iImage = m_iUnknown;
|
|
break;
|
|
}
|
|
|
|
if(ListView_InsertItem(m_hList,&item) == -1)
|
|
{
|
|
if(pSid)
|
|
{
|
|
delete pSid;
|
|
}
|
|
}
|
|
}
|
|
|
|
NetApiBufferFree(plmi2);
|
|
}
|
|
|
|
//If list is not empty, set focus on the first item.
|
|
if( ListView_GetItemCount(m_hList) )
|
|
{
|
|
ListView_SetItemState(m_hList, 0, LVIS_FOCUSED, LVIS_FOCUSED );
|
|
}
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CRemoteUsersDialog::InitAccessMessage()
|
|
//
|
|
// Purpose: Check if current user has remote logon access
|
|
// and if he does, show corresponding text in the dialog.
|
|
//
|
|
// Parameters: NONE
|
|
//
|
|
// Return: NONE
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 01/04/01 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
void
|
|
CRemoteUsersDialog::InitAccessMessage()
|
|
{
|
|
//First, get token handle
|
|
HANDLE hToken = NULL, hToken1 = NULL;
|
|
|
|
//Get Primary token
|
|
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE , &hToken))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//Get Impersonation token
|
|
if(!DuplicateToken(hToken, SecurityIdentification, &hToken1))
|
|
{
|
|
CloseHandle(hToken);
|
|
return;
|
|
}
|
|
|
|
CloseHandle(hToken);
|
|
|
|
//Get RDP-Tcp WinStation security descriptor.
|
|
PSECURITY_DESCRIPTOR pSD;
|
|
|
|
if(GetRDPSecurityDescriptor(&pSD))
|
|
{
|
|
if(CheckWinstationLogonAccess(hToken1,pSD))
|
|
{
|
|
//Extract the name of the user from the token.
|
|
LPWSTR szName = NULL;
|
|
if(GetTokenUserName(hToken1,&szName))
|
|
{
|
|
//If user is local, remove domain name
|
|
IsLocal(szName);
|
|
|
|
//Assemble a text for the message.
|
|
WCHAR szTemplate[MAX_PATH+1];
|
|
HWND hMessage = GetDlgItem(m_hDlg,IDC_USER_HAS_ACCESS);
|
|
if(hMessage &&
|
|
LoadString(m_hInst,IDS_USER_HAS_ASSESS,szTemplate,MAX_PATH))
|
|
{
|
|
LPWSTR szMessage = (LPWSTR) LocalAlloc(LPTR,
|
|
(wcslen(szTemplate)+wcslen(szName))*sizeof(WCHAR));
|
|
if(szMessage)
|
|
{
|
|
wsprintf(szMessage,szTemplate,szName);
|
|
SetWindowText(hMessage,szMessage);
|
|
|
|
LocalFree(szMessage);
|
|
}
|
|
}
|
|
|
|
LocalFree(szName);
|
|
}
|
|
}
|
|
LocalFree(pSD);
|
|
}
|
|
|
|
CloseHandle(hToken1);
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// GetTokenUserName()
|
|
//
|
|
// Purpose: Extracts a user name from the token.
|
|
//
|
|
// Parameters: IN HANDLE hToken
|
|
// OUT LPWSTR *ppName
|
|
//
|
|
// Return: TRUE - if success
|
|
// FALSE - in case of any error
|
|
//
|
|
// Comments: Caller should free memory allocated for user name
|
|
// using LocalFree function
|
|
//
|
|
// History: Date Author Comment
|
|
// 01/04/01 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
GetTokenUserName(
|
|
IN HANDLE hToken,
|
|
OUT LPWSTR *ppName)
|
|
{
|
|
*ppName = NULL;
|
|
|
|
DWORD dwReturnLength=0;
|
|
BOOL bResult = FALSE;
|
|
PTOKEN_USER pTUser = NULL;
|
|
|
|
if(!GetTokenInformation(hToken,TokenUser,NULL,0,&dwReturnLength) &&
|
|
GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
|
|
dwReturnLength)
|
|
{
|
|
pTUser = (PTOKEN_USER)LocalAlloc(LPTR,dwReturnLength);
|
|
if(pTUser)
|
|
{
|
|
if(GetTokenInformation(hToken,TokenUser,pTUser,dwReturnLength,&dwReturnLength))
|
|
{
|
|
//Get current user 's name.
|
|
LPWSTR szName = NULL;
|
|
SID_NAME_USE eUse;
|
|
|
|
return LookupSid(pTUser->User.Sid,ppName,&eUse);
|
|
}
|
|
|
|
LocalFree(pTUser);
|
|
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// GetRDPSecurityDescriptor()
|
|
//
|
|
// Purpose: Returns security descriptor for RDP-Tcp
|
|
//
|
|
// Parameters: OUT PSECURITY_DESCRIPTOR *ppSD
|
|
//
|
|
// Return: TRUE - if success
|
|
// FALSE - in case of any error
|
|
//
|
|
// Comments: Caller should free memory allocated for
|
|
// security descriptor using LocalFree function
|
|
//
|
|
// History: Date Author Comment
|
|
// 01/04/01 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
GetRDPSecurityDescriptor(
|
|
OUT PSECURITY_DESCRIPTOR *ppSD)
|
|
{
|
|
*ppSD = NULL;
|
|
|
|
if( FAILED( CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
ICfgComp *pCfgcomp;
|
|
|
|
if( SUCCEEDED( CoCreateInstance( CLSID_CfgComp , NULL , CLSCTX_INPROC_SERVER ,
|
|
IID_ICfgComp , ( LPVOID *)&pCfgcomp ) ) )
|
|
{
|
|
LONG lSDsize;
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
|
|
if( SUCCEEDED( pCfgcomp->Initialize() ) &&
|
|
SUCCEEDED( pCfgcomp->GetSecurityDescriptor( L"RDP-Tcp" , &lSDsize , &pSD ) ) )
|
|
{
|
|
*ppSD = pSD;
|
|
}
|
|
|
|
pCfgcomp->Release();
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
return (*ppSD != NULL);
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CheckWinstationLogonAccess()
|
|
//
|
|
// Purpose: Tests access token for LOGON access to WinStation
|
|
//
|
|
// Parameters: IN HANDLE hToken
|
|
// IN PSECURITY_DESCRIPTOR pSD
|
|
//
|
|
// Return: TRUE - if user has access
|
|
// FALSE - in case of any error or if user
|
|
// does not have access
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 01/04/01 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
CheckWinstationLogonAccess(
|
|
IN HANDLE hToken,
|
|
IN PSECURITY_DESCRIPTOR pSD)
|
|
{
|
|
//this is taken from "termsrv\winsta\server\acl.c"
|
|
//
|
|
// Structure that describes the mapping of generic access rights to object
|
|
// specific access rights for Window Station objects.
|
|
//
|
|
GENERIC_MAPPING WinStaMapping = {
|
|
STANDARD_RIGHTS_READ |
|
|
WINSTATION_QUERY,
|
|
STANDARD_RIGHTS_WRITE |
|
|
WINSTATION_SET,
|
|
STANDARD_RIGHTS_EXECUTE,
|
|
WINSTATION_ALL_ACCESS
|
|
};
|
|
|
|
PRIVILEGE_SET PrivilegeSet;
|
|
//There are no privileges used for this access check
|
|
//so we don't need to allocate additional memory
|
|
DWORD dwPrivilegeSetLength = sizeof(PrivilegeSet);
|
|
DWORD dwGrantedAccess = 0;
|
|
BOOL bAccessStatus = FALSE;
|
|
|
|
if(!AccessCheck(
|
|
pSD, // SD
|
|
hToken, // handle to client access token
|
|
WINSTATION_LOGON, // requested access rights
|
|
&WinStaMapping, // mapping
|
|
&PrivilegeSet, // privileges
|
|
&dwPrivilegeSetLength, // size of privileges buffer
|
|
&dwGrantedAccess, // granted access rights
|
|
&bAccessStatus // result of access check
|
|
) || !bAccessStatus )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// LookupSid()
|
|
//
|
|
// Purpose: Given SID allocates and returns string containing
|
|
// name of the user in format DOMAINNAME\USERNAME
|
|
//
|
|
// Parameters: IN PSID pSid
|
|
// OUT LPWSTR ppName
|
|
// OUT SID_NAME_USE *peUse
|
|
//
|
|
// Return: TRUE if success, FALSE otherwise
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 10/23/00 skuzin Created
|
|
//
|
|
//*************************************************************
|
|
BOOL
|
|
LookupSid(
|
|
IN PSID pSid,
|
|
OUT LPWSTR *ppName,
|
|
OUT SID_NAME_USE *peUse)
|
|
{
|
|
LPWSTR szName = NULL;
|
|
DWORD cName = 0;
|
|
LPWSTR szDomainName = NULL;
|
|
DWORD cDomainName = 0;
|
|
|
|
*ppName = NULL;
|
|
|
|
if(!LookupAccountSidW(NULL,pSid,
|
|
szName,&cName,
|
|
szDomainName,&cDomainName,
|
|
peUse) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
//cName and cDomainName include terminating 0
|
|
*ppName = (LPWSTR)LocalAlloc(LPTR,(cName+cDomainName)*sizeof(WCHAR));
|
|
|
|
if(*ppName)
|
|
{
|
|
szDomainName = *ppName;
|
|
szName = &(*ppName)[cDomainName];
|
|
|
|
if(LookupAccountSidW(NULL,pSid,
|
|
szName,&cName,
|
|
szDomainName,&cDomainName,
|
|
peUse))
|
|
{
|
|
//user name now in format DOMAINNAME\0USERNAME
|
|
//let's replace '\0' with '\\'
|
|
//now cName and cDomainName do not include terminating 0
|
|
//very confusing
|
|
if(cDomainName)
|
|
{
|
|
(*ppName)[cDomainName] = L'\\';
|
|
}
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
LocalFree(*ppName);
|
|
*ppName = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|