828 lines
23 KiB
C++
828 lines
23 KiB
C++
//+---------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1993 - 1997.
|
|
//
|
|
// 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 "resource.h"
|
|
#include "clspsht.h"
|
|
#include "datapkt.h"
|
|
|
|
#if !defined(STANDALONE_BUILD)
|
|
extern "C"
|
|
{
|
|
#include <getuser.h>
|
|
}
|
|
#endif
|
|
|
|
#include "util.h"
|
|
#include "newsrvr.h"
|
|
|
|
#if !defined(STANDALONE_BUILD)
|
|
extern "C"
|
|
{
|
|
#include <sedapi.h>
|
|
#include <ntlsa.h>
|
|
}
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#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 == _tcsicmp(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 = (BYTE *)GlobalAlloc(GMEM_FIXED, 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 *pCdb = g_virtreg.GetAt(m_Page3.m_iAccessIndex);
|
|
pCdb->SetModified(FALSE);
|
|
}
|
|
GlobalFree(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 = (BYTE *)GlobalAlloc(GMEM_FIXED, 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 * pCdb = g_virtreg.GetAt(m_Page3.m_iLaunchIndex);
|
|
pCdb->SetModified(FALSE);
|
|
}
|
|
GlobalFree(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 = (BYTE *)GlobalAlloc(GMEM_FIXED, 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 = (BYTE *)GlobalAlloc(GMEM_FIXED, 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 * pCdb = g_virtreg.GetAt(m_Page3.m_iConfigurationIndex);
|
|
pCdb->SetModified(FALSE);
|
|
m_Page3.m_iConfig = 1;
|
|
}
|
|
}
|
|
GlobalFree(pbValue);
|
|
GlobalFree(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);
|
|
}
|
|
// add the property page for endpoint options
|
|
AddPage(&m_Page5);
|
|
m_Page5.InitData(szAppName, hkAppID);
|
|
|
|
|
|
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.ValidateChanges();
|
|
if (fReturn && m_Page2.m_hWnd)
|
|
fReturn = m_Page2.ValidateChanges();
|
|
if (fReturn && m_Page3.m_hWnd)
|
|
fReturn = m_Page3.ValidateChanges();
|
|
if (fReturn && m_Page4.m_hWnd)
|
|
fReturn = m_Page4.ValidateChanges();
|
|
|
|
if (fReturn && m_Page5.m_hWnd)
|
|
fReturn = m_Page5.ValidateChanges();
|
|
|
|
if (!fReturn)
|
|
return FALSE;
|
|
|
|
m_Page1.UpdateChanges(m_hkAppID);
|
|
m_Page2.UpdateChanges(m_hkAppID);
|
|
m_Page3.UpdateChanges(m_hkAppID);
|
|
m_Page4.UpdateChanges(m_hkAppID);
|
|
m_Page5.UpdateChanges(m_hkAppID);
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Persist cross page data
|
|
|
|
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;
|
|
}
|
|
|