1082 lines
30 KiB
C++
1082 lines
30 KiB
C++
//+---------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1993 - 1994.
|
|
//
|
|
// File: clspsht.cpp
|
|
//
|
|
// Contents: Implements class CClsidPropertySheet
|
|
//
|
|
// Classes:
|
|
//
|
|
// Methods: CClsidPropertySheet::CClsidPropertySheet
|
|
// CClsidPropertySheet::~CClsidPropertySheet
|
|
// CClsidPropertySheet::InitData
|
|
// CClsidPropertySheet::OnNcCreate
|
|
// CClsidPropertySheet::ValidateAndUpdate
|
|
// CClsidPropertySheet::OnCommand
|
|
// CClsidPropertySheet::LookAtCLSIDs
|
|
// CClsidPropertySheet::ChangeCLSIDInfo
|
|
//
|
|
// History: 23-Apr-96 BruceMa Created.
|
|
//
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "afxtempl.h"
|
|
#include "resource.h"
|
|
#include "clspsht.h"
|
|
#include "datapkt.h"
|
|
extern "C"
|
|
{
|
|
#include <getuser.h>
|
|
}
|
|
#include "util.h"
|
|
#include "newsrvr.h"
|
|
#include "datapkt.h"
|
|
#include "virtreg.h"
|
|
|
|
extern "C"
|
|
{
|
|
#include <sedapi.h>
|
|
#include <ntlsa.h>
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClsidPropertySheet
|
|
|
|
IMPLEMENT_DYNAMIC(CClsidPropertySheet, CPropertySheet)
|
|
|
|
CClsidPropertySheet::CClsidPropertySheet(CWnd* pParentWnd)
|
|
: CPropertySheet(IDS_PROPSHT_CAPTION1, pParentWnd)
|
|
{
|
|
}
|
|
|
|
CClsidPropertySheet::~CClsidPropertySheet()
|
|
{
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CClsidPropertySheet, CPropertySheet)
|
|
//{{AFX_MSG_MAP(CClsidPropertySheet)
|
|
ON_WM_NCCREATE()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
CClsidPropertySheet::InitData(
|
|
CString szAppName,
|
|
HKEY hkAppID,
|
|
HKEY * rghkCLSID,
|
|
unsigned cCLSIDs)
|
|
{
|
|
m_szAppName = szAppName;
|
|
m_hkAppID = hkAppID;
|
|
m_rghkCLSID = rghkCLSID;
|
|
m_cCLSIDs = cCLSIDs;
|
|
|
|
// Save the appid key, the table of clsid keys and the application
|
|
// title globally so the property pages can access them
|
|
// it
|
|
g_hAppid = hkAppID;
|
|
g_rghkCLSID = rghkCLSID;
|
|
g_cCLSIDs = cCLSIDs;
|
|
g_szAppTitle = (TCHAR *) LPCTSTR(szAppName);
|
|
|
|
m_Page2.m_fRemote = FALSE;
|
|
m_Page4.m_fService = FALSE;
|
|
m_Page2.m_fCanBeLocal = FALSE;
|
|
m_Page2.m_fLocal = FALSE;
|
|
m_Page1.m_fSurrogate = FALSE;
|
|
|
|
if (!LookAtCLSIDs())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
TCHAR szBuffer[MAX_PATH];
|
|
DWORD dwSize;
|
|
long lErr;
|
|
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
m_hkAppID,
|
|
TEXT("LocalService"),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
m_Page1.m_szServerPath = szBuffer;
|
|
m_Page4.m_fService = TRUE;
|
|
m_Page2.m_fCanBeLocal = TRUE;
|
|
m_Page2.m_fLocal = TRUE;
|
|
}
|
|
else
|
|
{
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
m_hkAppID,
|
|
TEXT("_LocalService"),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
m_Page1.m_szServerPath = szBuffer;
|
|
m_Page4.m_fService = TRUE;
|
|
m_Page2.m_fCanBeLocal = TRUE;
|
|
}
|
|
}
|
|
|
|
dwSize = sizeof(szBuffer);
|
|
|
|
if (!m_Page2.m_fLocal)
|
|
{
|
|
lErr = RegQueryValueEx(
|
|
m_hkAppID,
|
|
TEXT("DllSurrogate"),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
if (szBuffer[0])
|
|
m_Page1.m_szServerPath = szBuffer;
|
|
else
|
|
m_Page1.m_szServerPath.LoadString(IDS_DEFAULT);
|
|
m_Page1.m_fSurrogate = TRUE;
|
|
}
|
|
|
|
}
|
|
dwSize = sizeof(szBuffer);
|
|
|
|
lErr = RegQueryValueEx(
|
|
m_hkAppID,
|
|
TEXT("RemoteServerName"),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
m_Page1.m_szComputerName = szBuffer;
|
|
m_Page2.m_szComputerName = szBuffer;
|
|
m_Page2.m_fRemote = TRUE;
|
|
}
|
|
|
|
m_Page2.m_fAtStorage = FALSE;
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
m_hkAppID,
|
|
TEXT("ActivateAtStorage"),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
if (szBuffer[0] == L'Y' || szBuffer[0] == L'y')
|
|
{
|
|
// m_Page2.m_fRemote = TRUE;
|
|
m_Page2.m_fAtStorage = TRUE;
|
|
}
|
|
}
|
|
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
m_hkAppID,
|
|
TEXT("RunAs"),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
// If the RunAs name is empty, jam in something
|
|
if (szBuffer[0] == TEXT('\0'))
|
|
{
|
|
_tcscpy(szBuffer, TEXT("<domain>\\<user>"));
|
|
}
|
|
|
|
if (0 == _tcscmp(szBuffer, TEXT("Interactive User")))
|
|
{
|
|
m_Page4.m_iIdentity = 0;
|
|
}
|
|
else
|
|
{
|
|
m_Page4.m_iIdentity = 2;
|
|
m_Page4.m_szUserName = szBuffer;
|
|
|
|
// Extract password from the Lsa private database
|
|
g_util.RetrieveUserPassword(g_szAppid , m_Page4.m_szPassword);
|
|
m_Page4.m_szConfirmPassword = m_Page4.m_szPassword;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_Page4.m_fService)
|
|
{
|
|
m_Page4.m_iIdentity = 3;
|
|
}
|
|
else
|
|
{
|
|
m_Page4.m_iIdentity = 1;
|
|
}
|
|
}
|
|
|
|
m_Page1.m_szServerName = m_szAppName;
|
|
|
|
if (!m_Page1.m_fSurrogate)
|
|
{
|
|
if (m_Page2.m_fCanBeLocal)
|
|
{
|
|
if (m_Page4.m_fService)
|
|
m_Page1.m_iServerType = SERVICE;
|
|
else
|
|
m_Page1.m_iServerType = LOCALEXE;
|
|
if (m_Page2.m_fRemote)
|
|
m_Page1.m_iServerType += 3;
|
|
}
|
|
else
|
|
m_Page1.m_iServerType = PURE_REMOTE;
|
|
}
|
|
else
|
|
{
|
|
m_Page1.m_iServerType = SURROGATE;
|
|
}
|
|
|
|
|
|
// Set the title
|
|
SetTitle((const TCHAR *) m_szAppName, PSH_PROPTITLE);
|
|
m_Page1.m_szServerName = m_szAppName;
|
|
|
|
// TODO: If there are running instances, then make IDC_RUNNING,
|
|
// IDC_LIST2, IDC_BUTTON1, IDC_BUTTON2, and IDC_BUTTON3 visible
|
|
// and fill in IDC_LIST2 on page 1.
|
|
|
|
m_Page2.m_pPage1 = &m_Page1;
|
|
|
|
|
|
// Fetch RunAs key, LaunchPermission, AccessPermission and
|
|
// ConfigurationPermission
|
|
int err;
|
|
DWORD dwType;
|
|
BYTE bValue[16];
|
|
BYTE *pbValue = NULL;
|
|
ULONG ulSize = 1;
|
|
|
|
m_Page3.m_iAccess = 0;
|
|
m_Page3.m_iLaunch = 0;
|
|
m_Page3.m_iConfig = 0;
|
|
|
|
// "AccessPermission"
|
|
// Note: We always expect to get ERROR_MORE_DATA
|
|
err = RegQueryValueEx(g_hAppid, TEXT("AccessPermission"), 0,
|
|
&dwType, bValue, &ulSize);
|
|
if (err == ERROR_MORE_DATA)
|
|
{
|
|
pbValue = new BYTE[ulSize];
|
|
if (pbValue == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
err = RegQueryValueEx(g_hAppid, TEXT("AccessPermission"), 0,
|
|
&dwType, pbValue, &ulSize);
|
|
}
|
|
|
|
if (err == ERROR_SUCCESS && g_util.CheckForValidSD((SECURITY_DESCRIPTOR *)pbValue))
|
|
{
|
|
m_Page3.m_iAccess = 1;
|
|
g_virtreg.NewRegSingleACL(g_hAppid,
|
|
NULL,
|
|
TEXT("AccessPermission"),
|
|
(SECURITY_DESCRIPTOR *) pbValue,
|
|
TRUE, // Already in self-relative form
|
|
&m_Page3.m_iAccessIndex);
|
|
CDataPacket &cdb = g_virtreg.GetAt(m_Page3.m_iAccessIndex);
|
|
cdb.fDirty = FALSE;
|
|
}
|
|
delete pbValue;
|
|
pbValue = NULL;
|
|
|
|
// "LaunchPermission"
|
|
// Note: We always expect to get ERROR_MORE_DATA
|
|
ulSize = 1;
|
|
pbValue = NULL;
|
|
err = RegQueryValueEx(g_hAppid, TEXT("LaunchPermission"), 0,
|
|
&dwType, bValue, &ulSize);
|
|
if (err == ERROR_MORE_DATA)
|
|
{
|
|
pbValue = new BYTE[ulSize];
|
|
if (pbValue == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
err = RegQueryValueEx(g_hAppid, TEXT("LaunchPermission"), 0,
|
|
&dwType, pbValue, &ulSize);
|
|
}
|
|
|
|
if (err == ERROR_SUCCESS && g_util.CheckForValidSD((SECURITY_DESCRIPTOR *)pbValue))
|
|
{
|
|
m_Page3.m_iLaunch = 1;
|
|
g_virtreg.NewRegSingleACL(g_hAppid,
|
|
NULL,
|
|
TEXT("LaunchPermission"),
|
|
(SECURITY_DESCRIPTOR *) pbValue,
|
|
TRUE, // Already in self-relative form
|
|
&m_Page3.m_iLaunchIndex);
|
|
CDataPacket &cdb = g_virtreg.GetAt(m_Page3.m_iLaunchIndex);
|
|
cdb.fDirty = FALSE;
|
|
}
|
|
delete pbValue;
|
|
pbValue = NULL;
|
|
|
|
|
|
// "ConfigurationPermission"
|
|
|
|
// Fetch the security descriptor on this AppID
|
|
// Note: We always expect to get ERROR_INSUFFICIENT_BUFFER
|
|
ulSize = 1;
|
|
err = RegGetKeySecurity(g_hAppid,
|
|
OWNER_SECURITY_INFORMATION |
|
|
GROUP_SECURITY_INFORMATION |
|
|
DACL_SECURITY_INFORMATION,
|
|
pbValue,
|
|
&ulSize);
|
|
if (err == ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
pbValue = new BYTE[ulSize];
|
|
if (pbValue == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
err = RegGetKeySecurity(g_hAppid,
|
|
OWNER_SECURITY_INFORMATION |
|
|
GROUP_SECURITY_INFORMATION |
|
|
DACL_SECURITY_INFORMATION,
|
|
pbValue,
|
|
&ulSize);
|
|
}
|
|
|
|
// Fetch the current security descriptor on HKEY_CLASSES_ROOT
|
|
// Note: We always expect to get ERROR_INSUFFICIENT_BUFFER
|
|
BYTE *pbValue2 = NULL;
|
|
|
|
ulSize = 1;
|
|
pbValue2 = NULL;
|
|
err = RegGetKeySecurity(HKEY_CLASSES_ROOT,
|
|
OWNER_SECURITY_INFORMATION |
|
|
GROUP_SECURITY_INFORMATION |
|
|
DACL_SECURITY_INFORMATION,
|
|
pbValue2,
|
|
&ulSize);
|
|
if (err == ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
pbValue2 = new BYTE[ulSize];
|
|
if (pbValue2 == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
err = RegGetKeySecurity(HKEY_CLASSES_ROOT,
|
|
OWNER_SECURITY_INFORMATION |
|
|
GROUP_SECURITY_INFORMATION |
|
|
DACL_SECURITY_INFORMATION,
|
|
pbValue2,
|
|
&ulSize);
|
|
}
|
|
|
|
// Now compare them. If they differ then this AppId uses custom
|
|
// configuration permissions
|
|
|
|
if (err == ERROR_SUCCESS && g_util.CheckForValidSD((SECURITY_DESCRIPTOR *)pbValue))
|
|
{
|
|
if (!g_util.CompareSDs((PSrSecurityDescriptor) pbValue,
|
|
(PSrSecurityDescriptor) pbValue2))
|
|
{
|
|
err = g_virtreg.NewRegKeyACL(g_hAppid,
|
|
rghkCLSID,
|
|
cCLSIDs,
|
|
g_szAppTitle,
|
|
(SECURITY_DESCRIPTOR *) pbValue,
|
|
(SECURITY_DESCRIPTOR *) pbValue,
|
|
TRUE,
|
|
&m_Page3.m_iConfigurationIndex);
|
|
CDataPacket &cdb = g_virtreg.GetAt(m_Page3.m_iConfigurationIndex);
|
|
cdb.fDirty = FALSE;
|
|
m_Page3.m_iConfig = 1;
|
|
}
|
|
}
|
|
delete pbValue;
|
|
delete pbValue2;
|
|
|
|
|
|
// Add all of the property pages here. Note that
|
|
// the order that they appear in here will be
|
|
// the order they appear in on screen. By default,
|
|
// the first page of the set is the active one.
|
|
// One way to make a different property page the
|
|
// active one is to call SetActivePage().
|
|
|
|
AddPage(&m_Page1);
|
|
if (m_Page1.m_iServerType != SURROGATE)
|
|
{
|
|
AddPage(&m_Page2);
|
|
}
|
|
if (m_Page2.m_fCanBeLocal || m_Page1.m_fSurrogate)
|
|
{
|
|
AddPage(&m_Page3);
|
|
AddPage(&m_Page4);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClsidPropertySheet message handlers
|
|
|
|
|
|
BOOL CClsidPropertySheet::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (!CPropertySheet::OnNcCreate(lpCreateStruct))
|
|
return FALSE;
|
|
|
|
ModifyStyleEx(0, WS_EX_CONTEXTHELP);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CClsidPropertySheet::ValidateAndUpdate(void)
|
|
{
|
|
// Call update data on all initialized pages
|
|
// to make sure that their private member variables are correct.
|
|
long lErr;
|
|
|
|
BOOL fReturn = UpdateData(TRUE);
|
|
if (fReturn && m_Page1.m_hWnd)
|
|
fReturn = m_Page1.UpdateData(TRUE);
|
|
if (fReturn && m_Page2.m_hWnd)
|
|
fReturn = m_Page2.UpdateData(TRUE);
|
|
if (fReturn && m_Page3.m_hWnd)
|
|
fReturn = m_Page3.UpdateData(TRUE);
|
|
if (fReturn && m_Page4.m_hWnd)
|
|
fReturn = m_Page4.UpdateData(TRUE);
|
|
|
|
if (m_Page4.m_iIdentity == 2)
|
|
{
|
|
// Check that the username is not blank
|
|
if (_tcslen(m_Page4.m_szUserName) == 0)
|
|
{
|
|
CString szTemp;
|
|
szTemp.LoadString(IDS_BLANKUSERNAME);
|
|
MessageBox(szTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
// Check that the password is not blank
|
|
if (_tcslen(m_Page4.m_szPassword) == 0)
|
|
{
|
|
CString szTemp;
|
|
szTemp.LoadString(IDS_BLANKPASSWORD);
|
|
MessageBox(szTemp);
|
|
return FALSE;
|
|
}
|
|
*/
|
|
|
|
// Check that the password has been confirmed
|
|
if (m_Page4.m_szPassword != m_Page4.m_szConfirmPassword)
|
|
{
|
|
CString szTemp;
|
|
szTemp.LoadString(IDS_NOMATCH);
|
|
MessageBox(szTemp);
|
|
fReturn = FALSE;
|
|
}
|
|
CString szUserName;
|
|
CString szDomain;
|
|
int iSplitPoint = m_Page4.m_szUserName.ReverseFind('\\');
|
|
if (iSplitPoint < 0)
|
|
{
|
|
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
|
|
TCHAR *szNewDomain;
|
|
|
|
// user didn't specify a domain
|
|
szNewDomain = new TCHAR[MAX_COMPUTERNAME_LENGTH + 1];
|
|
if (szNewDomain == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
if (!GetComputerName(szNewDomain, &dwSize))
|
|
{
|
|
g_util.PostErrorMessage();
|
|
return FALSE;
|
|
}
|
|
szDomain = szNewDomain;
|
|
delete szNewDomain;
|
|
szUserName = m_Page4.m_szUserName;
|
|
m_Page4.m_szUserName = szDomain + "\\" + szUserName;
|
|
}
|
|
else
|
|
{
|
|
// user did specify a domain
|
|
szDomain = m_Page4.m_szUserName.Left(iSplitPoint);
|
|
szUserName = m_Page4.m_szUserName.Mid(iSplitPoint + 1);
|
|
}
|
|
|
|
|
|
// Validate the domain and user name
|
|
BOOL fOk = FALSE;
|
|
BYTE sid[256];
|
|
DWORD cbSid = 256;
|
|
TCHAR szAcctDomain[MAX_PATH];
|
|
DWORD cbAcctDomain = MAX_PATH * sizeof(TCHAR);
|
|
SID_NAME_USE acctType;
|
|
|
|
fOk = LookupAccountName(NULL,
|
|
(TCHAR *) ((LPCTSTR) szUserName),
|
|
sid,
|
|
&cbSid,
|
|
szAcctDomain,
|
|
&cbAcctDomain,
|
|
&acctType);
|
|
|
|
// if successful, then validate domain name and account type
|
|
if (fOk)
|
|
{
|
|
fOk = (_tcsicmp((TCHAR *) ((LPCTSTR) szDomain), szAcctDomain) == 0
|
|
&&
|
|
acctType == SidTypeUser);
|
|
|
|
// If still unsuccessful, then try to match the domain against
|
|
// this computer's name
|
|
if (!fOk)
|
|
{
|
|
TCHAR szThisComputer[MAX_COMPUTERNAME_LENGTH + 1];
|
|
DWORD dwSize;
|
|
|
|
if (GetComputerName(szThisComputer, &dwSize))
|
|
{
|
|
fOk = (_tcsicmp((TCHAR *) ((LPCTSTR) szThisComputer),
|
|
szAcctDomain) == 0
|
|
&&
|
|
acctType == SidTypeUser);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!fOk)
|
|
{
|
|
CString szTemp;
|
|
szTemp.LoadString(IDS_NOACCOUNT);
|
|
MessageBox(szTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// Write the RunAs password to the Lsa private database
|
|
// (Note: We do this even if it's a service since QueryServiceConfig
|
|
// doesn't return the password, though we can use ChangeServiceConfig
|
|
// to set the password in the service database.)
|
|
if (!g_util.StoreUserPassword(g_szAppid, m_Page4.m_szPassword))
|
|
{
|
|
g_util.PostErrorMessage();
|
|
}
|
|
|
|
// Add rights to this user's account for "SeBatchLogonRight"
|
|
int err;
|
|
|
|
if (err = g_util.SetAccountRights((LPCTSTR) szUserName,
|
|
SE_BATCH_LOGON_NAME)
|
|
!= ERROR_SUCCESS)
|
|
{
|
|
g_util.PostErrorMessage(err);
|
|
}
|
|
|
|
}
|
|
|
|
// Check that remote servers are valid connectable machines
|
|
if (m_Page2.m_fRemote)
|
|
{
|
|
if (!g_util.VerifyRemoteMachine((TCHAR *) LPCTSTR(m_Page2.m_szComputerName)))
|
|
{
|
|
fReturn = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
if (!fReturn)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Persist Location property page data
|
|
if (m_Page2.m_fAtStorage)
|
|
{
|
|
lErr = RegSetValueEx(
|
|
m_hkAppID,
|
|
TEXT("ActivateAtStorage"),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)TEXT("Y"),
|
|
sizeof(TCHAR) * 2);
|
|
}
|
|
else
|
|
{
|
|
lErr = RegDeleteValue(
|
|
m_hkAppID,
|
|
TEXT("ActivateAtStorage"));
|
|
}
|
|
|
|
|
|
if (m_Page2.m_fRemote)
|
|
{
|
|
lErr = RegSetValueEx(
|
|
m_hkAppID,
|
|
TEXT("RemoteServerName"),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)(LPCTSTR)m_Page2.m_szComputerName,
|
|
(1 + m_Page2.m_szComputerName.GetLength()) * sizeof(TCHAR));
|
|
}
|
|
else
|
|
{
|
|
lErr = RegDeleteValue(
|
|
m_hkAppID,
|
|
TEXT("RemoteServerName"));
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Persist Security property page data
|
|
|
|
// Access permissions
|
|
// Use default access permissions
|
|
if (m_Page3.m_iAccess == 0)
|
|
{
|
|
// Delete the local AccessPermission named value to force this
|
|
// AppID to use the default global named value DefaultAccessPermission
|
|
lErr = RegDeleteValue(m_hkAppID, TEXT("AccessPermission"));
|
|
}
|
|
|
|
// Use per AppID access permissions
|
|
else
|
|
{
|
|
// If the user edited security, then persist that now
|
|
if (m_Page3.m_iAccessIndex >= 0)
|
|
{
|
|
lErr = g_virtreg.Apply(m_Page3.m_iAccessIndex);
|
|
g_virtreg.Remove(m_Page3.m_iAccessIndex);
|
|
m_Page3.m_iAccessIndex = -1;
|
|
}
|
|
}
|
|
|
|
// Launch permissions
|
|
// Use default Launch permissions
|
|
if (m_Page3.m_iLaunch == 0)
|
|
{
|
|
// Delete the local LaunchPermission named value to force this
|
|
// AppID to use the default global named value DefaultLaunchPermission
|
|
lErr = RegDeleteValue(m_hkAppID, TEXT("LaunchPermission"));
|
|
}
|
|
|
|
// Use per AppID Launch permissions
|
|
else
|
|
{
|
|
// If the user edited security, then persist that now
|
|
if (m_Page3.m_iLaunchIndex >= 0)
|
|
{
|
|
lErr = g_virtreg.Apply(m_Page3.m_iLaunchIndex);
|
|
g_virtreg.Remove(m_Page3.m_iLaunchIndex);
|
|
m_Page3.m_iLaunchIndex = -1;
|
|
}
|
|
}
|
|
|
|
// Configuration permissions
|
|
// Only meaningful on a per AppID basis
|
|
// If the user edited configuration security, then persist that now
|
|
if (m_Page3.m_iConfigurationIndex >= 0)
|
|
{
|
|
lErr = g_virtreg.Apply(m_Page3.m_iConfigurationIndex);
|
|
g_virtreg.Remove(m_Page3.m_iConfigurationIndex);
|
|
m_Page3.m_iConfigurationIndex = -1;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Persist Identity property page data
|
|
switch (m_Page4.m_iIdentity)
|
|
{
|
|
case 0:
|
|
{
|
|
CString szTemp;
|
|
szTemp = TEXT("Interactive User");
|
|
lErr = RegSetValueEx(
|
|
m_hkAppID,
|
|
TEXT("RunAs"),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)(LPCTSTR)szTemp,
|
|
(1 + szTemp.GetLength()) * sizeof(TCHAR));
|
|
break;
|
|
}
|
|
|
|
case 1:
|
|
case 3:
|
|
lErr = RegDeleteValue(m_hkAppID,
|
|
TEXT("RunAs"));
|
|
break;
|
|
|
|
case 2:
|
|
lErr = RegSetValueEx(m_hkAppID,
|
|
TEXT("RunAs"),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)(LPCTSTR)m_Page4.m_szUserName,
|
|
(1 + m_Page4.m_szUserName.GetLength()) *
|
|
sizeof(TCHAR));
|
|
break;
|
|
}
|
|
|
|
if (m_Page4.m_fService)
|
|
{
|
|
if (m_Page2.m_fLocal)
|
|
{
|
|
BOOL fOk;
|
|
|
|
// Write the LocalService value to the registry
|
|
lErr = RegSetValueEx(
|
|
m_hkAppID,
|
|
TEXT("LocalService"),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)(LPCTSTR)m_Page1.m_szServerPath,
|
|
(1 + m_Page1.m_szServerPath.GetLength()) * sizeof (TCHAR));
|
|
lErr = RegDeleteValue(
|
|
m_hkAppID,
|
|
TEXT("_LocalService"));
|
|
|
|
// Persist information to the service manager database
|
|
if (m_Page4.m_iIdentity == 3)
|
|
{
|
|
fOk = g_util.ChangeService((LPCTSTR) m_Page1.m_szServerPath,
|
|
TEXT("LocalSystem"),
|
|
TEXT(""),
|
|
(LPCTSTR) m_Page1.m_szServerName);
|
|
}
|
|
else
|
|
{
|
|
fOk = g_util.ChangeService((LPCTSTR) m_Page1.m_szServerPath,
|
|
(LPCTSTR) m_Page4.m_szUserName,
|
|
(LPCTSTR) m_Page4.m_szPassword,
|
|
(LPCTSTR) m_Page1.m_szServerName);
|
|
}
|
|
if (!fOk)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lErr = RegSetValueEx(
|
|
m_hkAppID,
|
|
TEXT("_LocalService"),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)(LPCTSTR)m_Page1.m_szServerPath,
|
|
(1 + m_Page1.m_szServerPath.GetLength()) * sizeof (TCHAR));
|
|
lErr = RegDeleteValue(
|
|
m_hkAppID,
|
|
TEXT("LocalService"));
|
|
}
|
|
}
|
|
|
|
return ChangeCLSIDInfo(m_Page2.m_fLocal);
|
|
}
|
|
|
|
BOOL CClsidPropertySheet::OnCommand(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
case ID_APPLY_NOW:
|
|
if (!ValidateAndUpdate())
|
|
return TRUE;
|
|
break;
|
|
}
|
|
return CPropertySheet::OnCommand(wParam, lParam);
|
|
}
|
|
|
|
BOOL CClsidPropertySheet::LookAtCLSIDs(void)
|
|
{
|
|
BOOL fFoundLocalServer = FALSE;
|
|
TCHAR szBuffer[MAX_PATH];
|
|
DWORD dwSize;
|
|
HKEY hKey;
|
|
long lErr;
|
|
|
|
unsigned n = 0;
|
|
while (n < m_cCLSIDs && !fFoundLocalServer)
|
|
{
|
|
lErr = RegOpenKeyEx(
|
|
m_rghkCLSID[n],
|
|
TEXT("LocalServer32"),
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
m_Page1.m_szServerPath = szBuffer;
|
|
m_Page2.m_fLocal = TRUE;
|
|
m_Page2.m_fCanBeLocal = TRUE;
|
|
fFoundLocalServer = TRUE;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
|
|
if (!fFoundLocalServer)
|
|
{
|
|
lErr = RegOpenKeyEx(
|
|
m_rghkCLSID[n],
|
|
TEXT("LocalServer"),
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
m_Page1.m_szServerPath = szBuffer;
|
|
m_Page2.m_fLocal = TRUE;
|
|
m_Page2.m_fCanBeLocal = TRUE;
|
|
fFoundLocalServer = TRUE;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
if (!fFoundLocalServer)
|
|
{
|
|
lErr = RegOpenKeyEx(
|
|
m_rghkCLSID[n],
|
|
TEXT("_LocalServer32"),
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
m_Page1.m_szServerPath = szBuffer;
|
|
m_Page2.m_fCanBeLocal = TRUE;
|
|
fFoundLocalServer = TRUE;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
if (!fFoundLocalServer)
|
|
{
|
|
lErr = RegOpenKeyEx(
|
|
m_rghkCLSID[n],
|
|
TEXT("_LocalServer"),
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
m_Page1.m_szServerPath = szBuffer;
|
|
m_Page2.m_fCanBeLocal = TRUE;
|
|
fFoundLocalServer = TRUE;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
n++;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL CClsidPropertySheet::ChangeCLSIDInfo(BOOL fLocal)
|
|
{
|
|
TCHAR szBuffer[MAX_PATH];
|
|
CString szOld;
|
|
CString szNew;
|
|
CString szOld16;
|
|
CString szNew16;
|
|
DWORD dwSize;
|
|
HKEY hKey;
|
|
long lErr;
|
|
|
|
if (fLocal)
|
|
{
|
|
szOld = TEXT("_LocalServer32");
|
|
szNew = TEXT("LocalServer32");
|
|
szOld16 = TEXT("_LocalServer");
|
|
szNew16 = TEXT("LocalServer");
|
|
}
|
|
else
|
|
{
|
|
szOld = TEXT("LocalServer32");
|
|
szNew = TEXT("_LocalServer32");
|
|
szOld16 = TEXT("LocalServer");
|
|
szNew16 = TEXT("_LocalServer");
|
|
}
|
|
|
|
unsigned n = 0;
|
|
while (n < m_cCLSIDs)
|
|
{
|
|
// First do 32 servers
|
|
lErr = RegOpenKeyEx(
|
|
m_rghkCLSID[n],
|
|
szOld,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
HKEY hKeyNew;
|
|
DWORD dwDisp;
|
|
|
|
lErr = RegCreateKeyEx(
|
|
m_rghkCLSID[n],
|
|
szNew,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKeyNew,
|
|
&dwDisp);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
lErr = RegSetValueEx(
|
|
hKeyNew,
|
|
TEXT(""),
|
|
NULL,
|
|
REG_SZ,
|
|
(BYTE *)szBuffer,
|
|
dwSize);
|
|
RegCloseKey(hKeyNew);
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
lErr = RegDeleteKey(m_rghkCLSID[n], szOld);
|
|
}
|
|
|
|
|
|
// Then do 16 servers
|
|
lErr = RegOpenKeyEx(
|
|
m_rghkCLSID[n],
|
|
szOld16,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(szBuffer);
|
|
lErr = RegQueryValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szBuffer,
|
|
&dwSize);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
HKEY hKeyNew;
|
|
DWORD dwDisp;
|
|
|
|
lErr = RegCreateKeyEx(
|
|
m_rghkCLSID[n],
|
|
szNew16,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKeyNew,
|
|
&dwDisp);
|
|
if (lErr == ERROR_SUCCESS)
|
|
{
|
|
lErr = RegSetValueEx(
|
|
hKeyNew,
|
|
TEXT(""),
|
|
NULL,
|
|
REG_SZ,
|
|
(BYTE *)szBuffer,
|
|
dwSize);
|
|
RegCloseKey(hKeyNew);
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
lErr = RegDeleteKey(m_rghkCLSID[n], szOld16);
|
|
}
|
|
|
|
n++;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|