windows-nt/Source/XPSP1/NT/inetsrv/iis/ui/admin/mmc/minetmgr.cpp
2020-09-26 16:20:57 +08:00

707 lines
15 KiB
C++

/*++
Copyright (c) 1994-1998 Microsoft Corporation
Module Name :
minetmgr.cpp
Abstract:
Snapin object
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "inetmgr.h"
#include "initguid.h"
#include "cinetmgr.h"
#include "constr.h"
#include "mycomput.h"
//
// Registry Definitions
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
const LPCTSTR g_cszCLSID = _T("CLSID");
const LPCTSTR g_cszLS32 = _T("LocalServer32");
const LPCTSTR g_cszIPS32 = _T("InprocServer32");
const LPCTSTR g_cszMMCBasePath = _T("Software\\Microsoft\\MMC");
const LPCTSTR g_cszSnapins = _T("Snapins");
const LPCTSTR g_cszNameString = _T("NameString");
const LPCTSTR g_cszNameStringInd = _T("NameStringIndirect");
const LPCTSTR g_cszProvider = _T("Provider");
const LPCTSTR g_cszVersion = _T("Version");
const LPCTSTR g_cszStandAlone = _T("StandAlone");
const LPCTSTR g_cszNodeTypes = _T("NodeTypes");
const LPCTSTR g_cszAbout = _T("About");
const LPCTSTR g_cszExtensions = _T("Extensions");
const LPCTSTR g_cszNameSpace = _T("NameSpace");
const LPCTSTR g_cszDynamicExt = _T("Dynamic Extensions");
const LPCTSTR g_cszValProvider = _T("Microsoft");
const LPCTSTR g_cszValVersion = _T("5.0");
const LPCTSTR g_cszMyCompMsc = _T("%SystemRoot%\\system32\\compmgmt.msc");
const LPCTSTR g_cszServerAppsLoc = _T("System\\CurrentControlSet\\Control\\Server Applications");
CFlexComModule _Module;
HRESULT WINAPI
CFlexComModule::UpdateRegistryClass(
IN const CLSID & clsid,
IN LPCTSTR lpszProgID,
IN LPCTSTR lpszVerIndProgID,
IN UINT nDescID,
IN DWORD dwFlags,
IN BOOL bRegister
)
/*++
Routine Description:
Override of UpdateRegistry to change the path to a path that uses
a %systemroot%\... EXPAND_SZ path
Arguments:
const CLSID& clsid : GUID
LPCTSTR lpszProgID : Program ID
LPCTSTR lpszVerIndProgID : Version independent program ID
UINT nDescID : Description resource ID
DWORD dwFlags : Flags
BOOL bRegister : TRUE for register, FALSE for unregister
Return Value:
HRESULT
--*/
{
//
// Call base class as normal
//
CError err = CComModule::UpdateRegistryClass(
clsid,
lpszProgID,
lpszVerIndProgID,
nDescID,
dwFlags,
bRegister
);
if (bRegister && err.Succeeded())
{
CString str, strKey, strCLSID;
GUIDToCString(clsid, strCLSID);
//
// Change the path in InProcServer32/LocalServer32 to a
// REG_EXPAND_SZ path
//
strKey.Format(_T("%s\\%s"),
g_cszCLSID,
strCLSID
);
CRMCRegKey rkCLSID(HKEY_CLASSES_ROOT, strKey, KEY_ENUMERATE_SUB_KEYS);
if (!rkCLSID.Ok())
{
//
// This should have been created by
// _Module.RegisterServer
//
err.GetLastWinError();
return err;
}
//
// Look for inproc32 or local32
//
CRMCRegKey rkInProc(rkCLSID, g_cszIPS32);
CRMCRegKey rkLocProc(rkCLSID, g_cszLS32);
CRMCRegKey * prk = rkInProc.Ok()
? &rkInProc
: rkLocProc.Ok()
? &rkLocProc
: NULL;
if (prk == NULL)
{
err.GetLastWinError();
return err;
}
//
// Rewrite entry as an REG_EXPAND_SZ
//
err = prk->QueryValue(NULL, str);
if (err.Succeeded())
{
err = prk->SetValue(NULL, str, TRUE);
}
}
return err;
}
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_Snapin, CComponentDataImpl)
OBJECT_ENTRY(CLSID_About, CSnapinAboutImpl)
END_OBJECT_MAP()
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// Message Map
//
BEGIN_MESSAGE_MAP(CSnapinApp, CWinApp)
//{{AFX_MSG_MAP(CConfigDll)
//}}AFX_MSG_MAP
//
// Global help commands
//
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
ON_COMMAND(ID_CONTEXT_HELP, CWinApp::OnContextHelp)
END_MESSAGE_MAP()
#ifdef _DEBUG
//
// Allocation tracker
//
BOOL
TrackAllocHook(
IN size_t nSize,
IN BOOL bObject,
IN LONG lRequestNumber
)
{
//
// Track lRequestNumber here
//
//TRACEEOLID("allocation # " << lRequestNumber);
return TRUE;
}
#endif // _DEBUG
CSnapinApp::CSnapinApp()
/*++
Routine Description:
Constructor
Arguments:
None
Return Value:
N/A
--*/
: CWinApp()
{
#ifdef _DEBUG
afxMemDF |= checkAlwaysMemDF;
AfxSetAllocHook(TrackAllocHook);
#endif // _DEBUG
}
void
CSnapinApp::SetHelpPath(
IN CServerInfo * pItem OPTIONAL
)
/*++
Routine Description:
Change the default help path
Arguments:
CServerInfo * pItem : New help path owner or NULL to reset the help path
Return Value:
None
Notes:
A call to SetHelpPath() without parameters restores the help path.
The help handler for the snapin is used to support help for down-level
inetmgr extensions that do not have their own help handler. Since many
of these extensions are MFC-based, help is expected to be provided in the
CWinApp object.
--*/
{
if (pItem == NULL)
{
//
// Restore help path back to the inetmgr app
//
ASSERT(m_lpOriginalHelpPath != NULL);
m_pszHelpFilePath = m_strInetMgrHelpPath;
return;
}
//
// Set the current help path equal to the one expected
// from the config dll name
//
LPTSTR lpPath = m_strHelpPath.GetBuffer(MAX_PATH + 1);
::GetModuleFileName(pItem->QueryInstanceHandle(), lpPath, MAX_PATH);
LPTSTR lp2 = _tcsrchr(lpPath, _T('.'));
ASSERT(lp2 != NULL);
if (lp2 != NULL)
*lp2 = '\0';
m_strHelpPath.ReleaseBuffer();
m_strHelpPath += _T(".HLP");
m_pszHelpFilePath = m_strHelpPath;
}
BOOL
CSnapinApp::InitInstance()
/*++
Routine Description
Instance initiation handler
Arguments:
None
Return Value:
TRUE for success, FALSE for failure
--*/
{
_Module.Init(ObjectMap, m_hInstance);
//
// Save a pointer to the old help file
//
m_lpOriginalHelpPath = m_pszHelpFilePath;
//
// Build up inetmgr help path, expanding
// the help path if necessary.
//
CRMCRegKey rk(REG_KEY, SZ_PARAMETERS, KEY_READ);
rk.QueryValue(SZ_HELPPATH, m_strInetMgrHelpPath, EXPANSION_ON);
m_strInetMgrHelpPath += _T("\\inetmgr.hlp");
TRACEEOLID("Initialized help file " << m_strInetMgrHelpPath);
m_pszHelpFilePath = m_strInetMgrHelpPath;
return CWinApp::InitInstance();
}
int
CSnapinApp::ExitInstance()
/*++
Routine Description:
Exit instance handler
Arguments:
None
Return Value:
0 for success
--*/
{
_Module.Term();
//
// Restore original help file path so it can be deleted
//
ASSERT(m_lpOriginalHelpPath != NULL);
m_pszHelpFilePath = m_lpOriginalHelpPath;
return CWinApp::ExitInstance();
}
//
// Instantiate the app object
//
CSnapinApp theApp;
STDAPI
DllCanUnloadNow()
/*++
Routine Description:
Used to determine whether the DLL can be unloaded by OLE
Arguments:
None
Return Value:
HRESULT
--*/
{
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
#ifdef _DEBUG
HRESULT hr = ::AfxDllCanUnloadNow();
LONG l = _Module.GetLockCount();
TRACEEOLID("Module lock count " << l);
BOOL fCanUnLoad = (l == 0 && hr == S_OK);
#endif // _DEBUG
return (::AfxDllCanUnloadNow() == S_OK
&& _Module.GetLockCount() == 0) ? S_OK : S_FALSE;
}
STDAPI
DllGetClassObject(
IN REFCLSID rclsid,
IN REFIID riid,
IN LPVOID * ppv
)
/*++
Routine Description:
Returns a class factory to create an object of the requested type
Arguments:
REFCLSID rclsid
REFIID riid
LPVOID * ppv
Return Value:
HRESULT
--*/
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
STDAPI
DllRegisterServer()
/*++
Routine Description:
DllRegisterServer - Adds entries to the system registry
Arguments:
None.
Return Value:
HRESULT
--*/
{
//
// Registers object, typelib and all interfaces in typelib
//
CError err(_Module.RegisterServer(FALSE));
if (err.Failed())
{
return err;
}
CString str, strKey, strExtKey;
try
{
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
//
// Create the primary snapin nodes
//
CString strNameString((LPCTSTR)IDS_NODENAME);
CString strNameStringInd;
// Fix for bug 96801: moving strings from the Registry to resources (MUI requirement)
TCHAR path[MAX_PATH];
GetModuleFileName(_Module.GetResourceInstance(), path, MAX_PATH - 1);
strNameStringInd.Format(_T("@%s,-%d"), path, IDS_NODENAME);
TRACEEOLID("MUI-lized snapin name: " << strNameStringInd);
CString strProvider(g_cszValProvider);
CString strVersion(g_cszValVersion);
CString str;
strKey.Format(
_T("%s\\%s\\%s"),
g_cszMMCBasePath,
g_cszSnapins,
GUIDToCString(CLSID_Snapin, str)
);
TRACEEOLID(strKey);
CString strAbout;
GUIDToCString(CLSID_About, strAbout);
CRMCRegKey rkSnapins(NULL, HKEY_LOCAL_MACHINE, strKey);
rkSnapins.SetValue(g_cszAbout, strAbout);
rkSnapins.SetValue(g_cszNameString, strNameString);
rkSnapins.SetValue(g_cszNameStringInd, strNameStringInd);
rkSnapins.SetValue(g_cszProvider, strProvider);
rkSnapins.SetValue(g_cszVersion, strVersion);
CRMCRegKey rkStandAlone(NULL, rkSnapins, g_cszStandAlone);
CRMCRegKey rkNodeTypes (NULL, rkSnapins, g_cszNodeTypes);
//
// Create the nodetype GUIDS
//
CRMCRegKey rkN1(NULL, rkNodeTypes, GUIDToCString(cInternetRootNode, str));
CRMCRegKey rkN2(NULL, rkNodeTypes, GUIDToCString(cMachineNode, str));
CRMCRegKey rkN3(NULL, rkNodeTypes, GUIDToCString(cInstanceNode, str));
CRMCRegKey rkN4(NULL, rkNodeTypes, GUIDToCString(cChildNode, str));
CRMCRegKey rkN5(NULL, rkNodeTypes, GUIDToCString(cFileNode, str));
{
//
// Register as a dynamic extension to computer management
//
strExtKey.Format(
_T("%s\\%s\\%s\\%s"),
g_cszMMCBasePath,
g_cszNodeTypes,
lstruuidNodetypeServerApps,
g_cszDynamicExt
);
TRACEEOLID(strExtKey);
CRMCRegKey rkMMCNodeTypes(NULL, HKEY_LOCAL_MACHINE, strExtKey);
rkMMCNodeTypes.SetValue(
GUIDToCString(CLSID_Snapin, str),
strNameString
);
}
{
//
// Register as a namespace extension to computer management
//
strExtKey.Format(
_T("%s\\%s\\%s\\%s\\%s"),
g_cszMMCBasePath,
g_cszNodeTypes,
lstruuidNodetypeServerApps,
g_cszExtensions,
g_cszNameSpace
);
TRACEEOLID(strExtKey);
CRMCRegKey rkMMCNodeTypes(NULL, HKEY_LOCAL_MACHINE, strExtKey);
rkMMCNodeTypes.SetValue(
GUIDToCString(CLSID_Snapin, str),
strNameString
);
}
//
// This key indicates that the service in question is available
// on the local machine
//
CRMCRegKey rkCompMgmt(
NULL,
HKEY_LOCAL_MACHINE,
g_cszServerAppsLoc
);
GUIDToCString(CLSID_Snapin, str);
rkCompMgmt.SetValue(
GUIDToCString(CLSID_Snapin, str),
strNameString
);
}
catch(CMemoryException * e)
{
e->Delete();
err = ERROR_NOT_ENOUGH_MEMORY;
}
catch(COleException * e)
{
e->Delete();
err = SELFREG_E_CLASS;
}
return err;
}
STDAPI
DllUnregisterServer()
/*++
Routine Description:
DllUnregisterServer - Removes entries from the system registry
Arguments:
None.
Return Value:
HRESULT
--*/
{
CError err;
try
{
CString strKey(g_cszMMCBasePath);
strKey += _T("\\");
strKey += g_cszSnapins;
TRACEEOLID(strKey);
CRMCRegKey rkBase(HKEY_LOCAL_MACHINE, strKey);
CString str, strExtKey;
{
CRMCRegKey rkCLSID(rkBase, GUIDToCString(CLSID_Snapin, str));
::RegDeleteKey(rkCLSID, g_cszStandAlone);
{
CRMCRegKey rkNodeTypes(rkCLSID, g_cszNodeTypes);
::RegDeleteKey(rkNodeTypes, GUIDToCString(cInternetRootNode, str));
::RegDeleteKey(rkNodeTypes, GUIDToCString(cMachineNode, str));
::RegDeleteKey(rkNodeTypes, GUIDToCString(cInstanceNode, str));
::RegDeleteKey(rkNodeTypes, GUIDToCString(cChildNode, str));
::RegDeleteKey(rkNodeTypes, GUIDToCString(cFileNode, str));
}
::RegDeleteKey(rkCLSID, g_cszNodeTypes);
}
::RegDeleteKey(rkBase, GUIDToCString(CLSID_Snapin, str));
{
//
// Delete a dynamic extension to computer management
//
strExtKey.Format(
_T("%s\\%s\\%s\\%s"),
g_cszMMCBasePath,
g_cszNodeTypes,
lstruuidNodetypeServerApps,
g_cszDynamicExt
);
CRMCRegKey rkMMCNodeTypes(HKEY_LOCAL_MACHINE, strExtKey);
::RegDeleteValue(rkMMCNodeTypes, GUIDToCString(CLSID_Snapin, str));
}
{
//
// Delete the namespace extension to computer management
//
strExtKey.Format(
_T("%s\\%s\\%s\\%s\\%s"),
g_cszMMCBasePath,
g_cszNodeTypes,
lstruuidNodetypeServerApps,
g_cszExtensions,
g_cszNameSpace
);
CRMCRegKey rkMMCNodeTypes(HKEY_LOCAL_MACHINE, strExtKey);
::RegDeleteValue(rkMMCNodeTypes, GUIDToCString(CLSID_Snapin, str));
}
//
// And the service itself no longer available on the local
// computer
//
CRMCRegKey rkCompMgmt(
HKEY_LOCAL_MACHINE,
g_cszServerAppsLoc
);
::RegDeleteValue(rkCompMgmt, GUIDToCString(CLSID_Snapin, str));
}
catch(CException * e)
{
err.GetLastWinError();
e->Delete();
}
if (err.Failed())
{
return err.Failed();
}
return _Module.UnregisterServer();
}